summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2012-06-20 22:59:03 +0200
committerAndrea Canciani <ranma42@gmail.com>2012-07-31 16:06:33 +0200
commit77db90242f7b7f12c5792480a10eb3a448e6c55f (patch)
treed636d581e466fb5590821adeb7beb349bf5d6a2c
parent5a094c70d4d9ae35afacd8d4fe0bb6e4bd1ba51b (diff)
test: Add test for TLS leakage
Add a test to expose the bug reported in: https://bugs.freedesktop.org/show_bug.cgi?id=34842
-rw-r--r--.gitignore1
-rw-r--r--configure.ac6
-rw-r--r--test/Makefile.sources1
-rw-r--r--test/limitmem.h53
-rw-r--r--test/tls-leak-test.c74
5 files changed, 135 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index a4d9f99..08c9834 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,7 @@ test/scaling-helpers-test
test/scaling-test
test/screen-test
test/stress-test
+test/tls-leak-test
test/trap-crasher
test/trap-test
test/window-test
diff --git a/configure.ac b/configure.ac
index bea674f..264e99e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -852,6 +852,12 @@ if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Whether we have gettimeofday()])
fi
+AC_CHECK_FUNC(setrlimit, have_setrlimit=yes, have_setrlimit=no)
+AC_CHECK_HEADER(sys/resource.h, have_sys_resource_h=yes, have_sys_resource_h=no)
+if test x$have_setrlimit = xyes && test x$have_sys_time_h = xyes && test x$have_sys_resource_h = xyes; then
+ AC_DEFINE(HAVE_SETRLIMIT, 1, [Whether we have setrlimit()])
+fi
+
dnl =====================================
dnl Thread local storage
diff --git a/test/Makefile.sources b/test/Makefile.sources
index fad8c6f..dd37c43 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -11,6 +11,7 @@ TESTPROGRAMS = \
scaling-crash-test \
scaling-helpers-test \
gradient-crash-test \
+ tls-leak-test \
region-contains-test \
alphamap \
stress-test \
diff --git a/test/limitmem.h b/test/limitmem.h
new file mode 100644
index 0000000..31eb517
--- /dev/null
+++ b/test/limitmem.h
@@ -0,0 +1,53 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#elif HAVE_SETRLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#endif
+
+
+int limitmem (size_t size)
+{
+#ifdef _WIN32
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limits;
+ HANDLE job;
+
+ memset (&limits, 0, sizeof (limits));
+ limits.ProcessMemoryLimit = size;
+ limits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
+
+ job = CreateJobObject (NULL, NULL);
+ if (job == NULL ||
+ ! AssignProcessToJobObject (job, GetCurrentProcess()) ||
+ ! SetInformationJobObject (job, JobObjectExtendedLimitInformation,
+ &limits, sizeof (limits)))
+ {
+ return -1;
+ }
+
+ return 0;
+
+#elif HAVE_SETRLIMIT
+ struct rlimit limit;
+
+ limit.rlim_cur = size;
+ limit.rlim_max = size;
+
+ return setrlimit (RLIMIT_AS, &limit);
+
+#else
+ fprintf (stderr, "Cannot set memory limit.\n");
+ return -1;
+
+#endif
+}
diff --git a/test/tls-leak-test.c b/test/tls-leak-test.c
new file mode 100644
index 0000000..a688d0e
--- /dev/null
+++ b/test/tls-leak-test.c
@@ -0,0 +1,74 @@
+#include <stdlib.h>
+#include "limitmem.h"
+#include "utils.h"
+
+#include "simpleops/thread/simpleops-thread.h"
+
+/* On most architectures it's actually more than this */
+#define TLS_SIZE 256
+
+#define MAX_SIZE (4 * 16 * 1024 * 1024)
+#define MAX_THREADS 4
+#define MAX_ITERS (((MAX_SIZE / MAX_THREADS) + TLS_SIZE) / TLS_SIZE)
+
+#define WIDTH 16
+#define HEIGHT 16
+
+static uint32_t *dest;
+static pixman_image_t *dest_img, *src_img;
+
+static void *thread_fun (void *arg)
+{
+ pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dest_img,
+ 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ simpleops_thread_t thread[MAX_THREADS];
+ pixman_color_t color;
+ int i, j, k, ret = 0;
+
+ if (limitmem (MAX_SIZE))
+ return -1;
+
+ dest = malloc (WIDTH * HEIGHT * 4);
+ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+ WIDTH, HEIGHT,
+ dest,
+ WIDTH * 4);
+
+ color.alpha = 45678;
+ color.red = 12345;
+ color.green = 23456;
+ color.blue = 34567;
+
+ src_img = pixman_image_create_solid_fill (&color);
+
+ for (i = 0; ret == 0 && i < MAX_ITERS; i++)
+ {
+ for (j = 0; j < MAX_THREADS; j++)
+ {
+ if (! simpleops_thread_create (&thread[j], thread_fun, NULL))
+ {
+ ret = -1;
+ break;
+ }
+ }
+
+ for (k = 0; k < j; k++)
+ {
+ if (! simpleops_thread_join (thread[k], NULL))
+ ret = -1;
+ }
+ }
+
+ pixman_image_unref (src_img);
+ pixman_image_unref (dest_img);
+ free (dest);
+
+ return ret;
+}