Add test cases for stack unwinding.

This commit is contained in:
David Xu 2010-09-25 04:26:40 +00:00
parent 6f066bb387
commit e04b953e48
8 changed files with 265 additions and 0 deletions

View File

@ -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

View File

@ -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");
}

View File

@ -0,0 +1,35 @@
/* $FreeBSD$ */
/* try to catch thread exiting, and rethrow the exception */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
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);
}

View File

@ -0,0 +1,39 @@
/* $FreeBSD$ */
/* Test stack unwinding for pthread_cond_wait function */
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#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);
}

View File

@ -0,0 +1,56 @@
/*
* $FreeBSD$
*
* 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"
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);
}

View File

@ -0,0 +1,18 @@
/* $FreeBSD$ */
/* 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);
}

View File

@ -0,0 +1,35 @@
/* $FreeBSD$ */
/* Test stack unwinding for libc's sem */
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#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);
}

View File

@ -0,0 +1,28 @@
/* $FreeBSD$ */
/* test stack unwinding for a new thread */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#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);
}