diff options
Diffstat (limited to 'pstack/linuxthreads.c')
-rw-r--r-- | pstack/linuxthreads.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c new file mode 100644 index 00000000000..8624bd21782 --- /dev/null +++ b/pstack/linuxthreads.c @@ -0,0 +1,90 @@ +/* $Header$ */ + +/* + * LinuxThreads specific stuff. + */ + +#include <sys/types.h> + +#include <assert.h> +#include <limits.h> /* PTHREAD_THREADS_MAX */ +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <sched.h> + +#include "linuxthreads.h" + +#define AT_INT(intval) *((int32_t*)(intval)) + +/* + * Internal LinuxThreads variables. + * Official interface exposed to GDB. + */ +#if 1 +extern volatile int __pthread_threads_debug; +extern volatile char __pthread_handles; +extern char __pthread_initial_thread; +/*extern volatile Elf32_Sym* __pthread_manager_thread;*/ +extern const int __pthread_sizeof_handle; +extern const int __pthread_offsetof_descr; +extern const int __pthread_offsetof_pid; +extern volatile int __pthread_handles_num; +#endif /* 0 */ + +/* + * Notify others. + */ +int +linuxthreads_notify_others( const int signotify) +{ + const pid_t mypid = getpid(); + //const pthread_t mytid = pthread_self(); + int i; + int threadcount = 0; + int threads[PTHREAD_THREADS_MAX]; + int pid; + + TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num)); + if (__pthread_handles_num==2) { + /* no threads beside the initial thread */ + return 0; + } + /*assert(maxthreads>=3); + assert(maxthreads>=__pthread_handles_num+2);*/ + + // take the initial thread with us + pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid); + if (pid!=mypid && pid!=0) + threads[threadcount++] = pid; + // don't know why, but always handles[0]==handles[1] + for (i=1; i<__pthread_handles_num; ++i) { + const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr); + assert(descr!=0); + pid = AT_INT(descr+__pthread_offsetof_pid); + if (pid!=mypid && pid!=0) + threads[threadcount++] = pid; + } + /* TRACE_FPRINTF((stderr, "Stopping threads...")); */ + //for (i=0; i<threadcount; ++i) { + // /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */ + // fflush(stdout); + // kill(threads[i], SIGSTOP); /* Tell thread to stop */ + //} + /* TRACE_FPRINTF((stderr, " done!\n")); */ + for (i=0; i<threadcount; ++i) { + TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i])); + kill(threads[i], signotify); /* Tell to print stack trace */ + /* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */ + /*pause(); Wait for confirmation. */ + } + for (i=0; i<threadcount; ++i) + sched_yield(); + for (i=0; i<threadcount; ++i) { + TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i])); + kill(threads[i], SIGKILL); /* Tell thread die :) */ + } + return __pthread_handles_num; +} + |