diff options
Diffstat (limited to 'tools/regression/pthread/unwind')
| -rw-r--r-- | tools/regression/pthread/unwind/Makefile | 16 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/Test.cpp | 36 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/catch_pthread_exit.cpp | 34 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/cond_wait_cancel.cpp | 38 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/cond_wait_cancel2.cpp | 55 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/main_thread_exit.cpp | 17 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/sem_wait_cancel.cpp | 34 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/thread_normal_exit.cpp | 27 | 
8 files changed, 257 insertions, 0 deletions
diff --git a/tools/regression/pthread/unwind/Makefile b/tools/regression/pthread/unwind/Makefile new file mode 100644 index 000000000000..33d3787c0ee3 --- /dev/null +++ b/tools/regression/pthread/unwind/Makefile @@ -0,0 +1,16 @@ +all: main_thread_exit thread_normal_exit sem_wait_cancel \ +     cond_wait_cancel cond_wait_cancel2 catch_pthread_exit + +.cpp: +	c++ -o $@ $< -lpthread +	 +main_thread_exit: main_thread_exit.cpp +thread_normal_exit: thread_normal_exit.cpp +sem_wait_cancel: sem_wait_cancel.cpp +cond_wait_cancel: cond_wait_cancel.cpp +cond_wait_cancel2: cond_wait_cancel2.cpp +catch_pthread_exit: catch_pthread_exit.cpp + +clean: .PHONY +	rm -rf main_thread_exit thread_normal_exit sem_wait_cancel \ +	cond_wait_cancel cond_wait_cancel2 catch_pthread_exit diff --git a/tools/regression/pthread/unwind/Test.cpp b/tools/regression/pthread/unwind/Test.cpp new file mode 100644 index 000000000000..bad63be44798 --- /dev/null +++ b/tools/regression/pthread/unwind/Test.cpp @@ -0,0 +1,36 @@ + +static int destructed; +static int destructed2; + +class Test { +public: +	Test() { printf("Test::Test()\n"); } +	~Test() { printf("Test::~Test()\n"); destructed = 1; } +}; + +void +cleanup_handler(void *arg __unused) +{ +	destructed2 = 1; +	printf("%s()\n", __func__); +} + +void +check_destruct(void) +{ +	if (!destructed) +		printf("Bug, object destructor is not called\n"); +	else +		printf("OK\n"); +} + +void +check_destruct2(void) +{ +	if (!destructed) +		printf("Bug, object destructor is not called\n"); +	else if (!destructed2) +		printf("Bug, cleanup handler is not called\n"); +	else +		printf("OK\n"); +} diff --git a/tools/regression/pthread/unwind/catch_pthread_exit.cpp b/tools/regression/pthread/unwind/catch_pthread_exit.cpp new file mode 100644 index 000000000000..b5074cd4beb1 --- /dev/null +++ b/tools/regression/pthread/unwind/catch_pthread_exit.cpp @@ -0,0 +1,34 @@ +/* try to catch thread exiting, and rethrow the exception */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +static int caught; + +static void * +thr_routine(void *arg __unused) +{ +	try { +		pthread_exit(NULL); +	} catch (...) { +		caught = 1; +		printf("thread exiting exception caught\n"); +		/* rethrow */ +		throw; +	} +} + +int +main() +{ +	pthread_t td; + +	pthread_create(&td, NULL, thr_routine, NULL); +	pthread_join(td, NULL); +	if (caught) +		printf("OK\n"); +	else +		printf("failure\n"); +	return (0); +} diff --git a/tools/regression/pthread/unwind/cond_wait_cancel.cpp b/tools/regression/pthread/unwind/cond_wait_cancel.cpp new file mode 100644 index 000000000000..d241b55909b6 --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel.cpp @@ -0,0 +1,38 @@ +/* Test stack unwinding for pthread_cond_wait function */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static pthread_mutex_t mtx; +static pthread_cond_t cv; + +static void * +thr(void *arg __unused) +{ +	Test t; + +	pthread_mutex_lock(&mtx); +	pthread_cond_wait(&cv, &mtx); +	pthread_mutex_unlock(&mtx); +	printf("Bug, thread shouldn't be here.\n"); +	return (0); +} + +int +main() +{ +	pthread_t td; + +	pthread_mutex_init(&mtx, NULL); +	pthread_cond_init(&cv, NULL); +	pthread_create(&td, NULL, thr, NULL); +	sleep(1); +	pthread_cancel(td); +	pthread_join(td, NULL); +	check_destruct(); +	return (0); +} diff --git a/tools/regression/pthread/unwind/cond_wait_cancel2.cpp b/tools/regression/pthread/unwind/cond_wait_cancel2.cpp new file mode 100644 index 000000000000..1763e115435b --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel2.cpp @@ -0,0 +1,55 @@ +/* + * + * Test stack unwinding for mixed pthread_cleanup_push/pop and C++ + * object, both should work together. + * + */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static pthread_mutex_t mtx; +static pthread_cond_t cv; + +static void f() +{ +	Test t; + +	pthread_mutex_lock(&mtx); +	pthread_cond_wait(&cv, &mtx); +	pthread_mutex_unlock(&mtx); +	printf("Bug, thread shouldn't be here.\n"); +} + +static void g() +{ +	f(); +} + +static void * +thr(void *arg __unused) +{ +	pthread_cleanup_push(cleanup_handler, NULL); +	g(); +	pthread_cleanup_pop(0); +	return (0); +} + +int +main() +{ +	pthread_t td; + +	pthread_mutex_init(&mtx, NULL); +	pthread_cond_init(&cv, NULL); +	pthread_create(&td, NULL, thr, NULL); +	sleep(1); +	pthread_cancel(td); +	pthread_join(td, NULL); +	check_destruct2(); +	return (0); +} diff --git a/tools/regression/pthread/unwind/main_thread_exit.cpp b/tools/regression/pthread/unwind/main_thread_exit.cpp new file mode 100644 index 000000000000..c3ee859a5f0f --- /dev/null +++ b/tools/regression/pthread/unwind/main_thread_exit.cpp @@ -0,0 +1,17 @@ +/* check unwinding for main thread */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "Test.cpp" + +int +main() +{ +	Test test; + +	atexit(check_destruct); +	pthread_exit((void *)1); +	return (0); +} diff --git a/tools/regression/pthread/unwind/sem_wait_cancel.cpp b/tools/regression/pthread/unwind/sem_wait_cancel.cpp new file mode 100644 index 000000000000..45f881c521fe --- /dev/null +++ b/tools/regression/pthread/unwind/sem_wait_cancel.cpp @@ -0,0 +1,34 @@ +/* Test stack unwinding for libc's sem */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static sem_t sem; + +static void * +thr(void *arg __unused) +{ +	Test t; + +	sem_wait(&sem); +	printf("Bug, thread shouldn't be here.\n"); +	return (0); +} + +int +main() +{ +	pthread_t td; + +	sem_init(&sem, 0, 0); +	pthread_create(&td, NULL, thr, NULL); +	sleep(1); +	pthread_cancel(td); +	pthread_join(td, NULL); +	check_destruct(); +	return (0); +} diff --git a/tools/regression/pthread/unwind/thread_normal_exit.cpp b/tools/regression/pthread/unwind/thread_normal_exit.cpp new file mode 100644 index 000000000000..3549db432f38 --- /dev/null +++ b/tools/regression/pthread/unwind/thread_normal_exit.cpp @@ -0,0 +1,27 @@ +/* test stack unwinding for a new thread */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "Test.cpp" + +static void * +thr_routine(void *arg __unused) +{ +	Test test; + +	pthread_exit(NULL); +	printf("Bug, thread shouldn't be here\n"); +} + +int +main() +{ +	pthread_t td; + +	pthread_create(&td, NULL, thr_routine, NULL); +	pthread_join(td, NULL); +	check_destruct(); +	return (0); +}  | 
