From b9b7f896c0989ace786c4764b1af88925c7291ec Mon Sep 17 00:00:00 2001 From: davidxu Date: Sat, 25 Sep 2010 04:26:40 +0000 Subject: Add test cases for stack unwinding. --- tools/regression/pthread/unwind/Makefile | 17 +++++++ tools/regression/pthread/unwind/Test.cpp | 37 ++++++++++++++ .../pthread/unwind/catch_pthread_exit.cpp | 35 ++++++++++++++ .../regression/pthread/unwind/cond_wait_cancel.cpp | 39 +++++++++++++++ .../pthread/unwind/cond_wait_cancel2.cpp | 56 ++++++++++++++++++++++ .../regression/pthread/unwind/main_thread_exit.cpp | 18 +++++++ .../regression/pthread/unwind/sem_wait_cancel.cpp | 35 ++++++++++++++ .../pthread/unwind/thread_normal_exit.cpp | 28 +++++++++++ 8 files changed, 265 insertions(+) create mode 100644 tools/regression/pthread/unwind/Makefile create mode 100644 tools/regression/pthread/unwind/Test.cpp create mode 100644 tools/regression/pthread/unwind/catch_pthread_exit.cpp create mode 100644 tools/regression/pthread/unwind/cond_wait_cancel.cpp create mode 100644 tools/regression/pthread/unwind/cond_wait_cancel2.cpp create mode 100644 tools/regression/pthread/unwind/main_thread_exit.cpp create mode 100644 tools/regression/pthread/unwind/sem_wait_cancel.cpp create mode 100644 tools/regression/pthread/unwind/thread_normal_exit.cpp (limited to 'tools') diff --git a/tools/regression/pthread/unwind/Makefile b/tools/regression/pthread/unwind/Makefile new file mode 100644 index 0000000..c4f9ac8 --- /dev/null +++ b/tools/regression/pthread/unwind/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ +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 0000000..9322def --- /dev/null +++ b/tools/regression/pthread/unwind/Test.cpp @@ -0,0 +1,37 @@ +/* $FreeBSD$ */ + +int destructed; +int destructed2; + +class Test { +public: + Test() { printf("Test::Test()\n"); } + ~Test() { printf("Test::~Test()\n"); destructed = 1; } +}; + +void +cleanup_handler(void *arg) +{ + 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 0000000..15abc20 --- /dev/null +++ b/tools/regression/pthread/unwind/catch_pthread_exit.cpp @@ -0,0 +1,35 @@ +/* $FreeBSD$ */ +/* try to catch thread exiting, and rethrow the exception */ + +#include +#include +#include + +int caught; + +void * +thr_routine(void *arg) +{ + 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 0000000..5975e02 --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel.cpp @@ -0,0 +1,39 @@ +/* $FreeBSD$ */ +/* Test stack unwinding for pthread_cond_wait function */ + +#include +#include +#include +#include + +#include "Test.cpp" + +pthread_mutex_t mtx; +pthread_cond_t cv; + +void * +thr(void *arg) +{ + 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 0000000..c781068 --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel2.cpp @@ -0,0 +1,56 @@ +/* + * $FreeBSD$ + * + * Test stack unwinding for mixed pthread_cleanup_push/pop and C++ + * object, both should work together. + * + */ + +#include +#include +#include +#include + +#include "Test.cpp" + +pthread_mutex_t mtx; +pthread_cond_t cv; + +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"); +} + +void g() +{ + f(); +} + +void * +thr(void *arg) +{ + 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 0000000..182c194 --- /dev/null +++ b/tools/regression/pthread/unwind/main_thread_exit.cpp @@ -0,0 +1,18 @@ +/* $FreeBSD$ */ +/* check unwinding for main thread */ + +#include +#include +#include + +#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 0000000..019164c --- /dev/null +++ b/tools/regression/pthread/unwind/sem_wait_cancel.cpp @@ -0,0 +1,35 @@ +/* $FreeBSD$ */ +/* Test stack unwinding for libc's sem */ + +#include +#include +#include +#include + +#include "Test.cpp" + +sem_t sem; + +void * +thr(void *arg) +{ + 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 0000000..faf900e --- /dev/null +++ b/tools/regression/pthread/unwind/thread_normal_exit.cpp @@ -0,0 +1,28 @@ +/* $FreeBSD$ */ +/* test stack unwinding for a new thread */ + +#include +#include +#include + +#include "Test.cpp" + +void * +thr_routine(void *arg) +{ + 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); +} -- cgit v1.1