Ticket #3692: pthreaddbg.c

File pthreaddbg.c, 21.8 KB (added by anonymous, 13 years ago)

library wrapper to keep track of stack-allocation in pthreads

Line 
1//gcc -g -o libpthreaddbg.so -shared pthreaddbg.c -ldl
2
3#define _GNU_SOURCE
4#include <stdlib.h>
5#include <stdio.h>
6#include <dlfcn.h>
7#include <pthread.h>
8#include <gnu/lib-names.h>
9#include <execinfo.h>
10#include <sys/types.h>
11#include <unistd.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <string.h>
16#include <time.h>
17
18//The following represents how much of the stack is already used
19//When we can 1st access it.  It is likely to be different for
20//different pthread libs and platforms
21#define PTHREAD_OFFSET_MAGIC 0x1ba8
22static int fd;
23static char printstr[2048];
24static int threadcount = 0;
25static pthread_mutex_t printlock = PTHREAD_MUTEX_INITIALIZER;
26
27struct pstack_t {
28  int    used;
29  int    thread_num;
30  unsigned int start;
31  unsigned int end;
32};
33#define PSTACK_SIZE 4096
34struct pstack_t *pstack;
35
36static int (*ppthread_create)(pthread_t *__restrict __threadp,
37                           __const pthread_attr_t *__restrict __attr,
38                           void *(*__start_routine) (void *),
39                           void *__restrict __arg) ;
40static pthread_t (*ppthread_self)(void) ;
41static int (*ppthread_equal)(pthread_t __thread1, pthread_t __thread2) ;
42static void (*ppthread_exit)(void *__retval)  __attribute__ ((__noreturn__));
43static int (*ppthread_join)(pthread_t __th, void **__thread_return);
44static int (*ppthread_detach)(pthread_t __th) ;
45static int (*ppthread_attr_init)(pthread_attr_t *__attr) ;
46static int (*ppthread_attr_destroy)(pthread_attr_t *__attr) ;
47static int (*ppthread_attr_setdetachstate)(pthread_attr_t *__attr,
48                                        int __detachstate) ;
49static int (*ppthread_attr_getdetachstate)(__const pthread_attr_t *__attr,
50                                        int *__detachstate) ;
51static int (*ppthread_attr_setschedparam)(pthread_attr_t *__restrict __attr,
52                                       __const struct sched_param *__restrict
53                                       __param) ;
54static int (*ppthread_attr_getschedparam)(__const pthread_attr_t *__restrict
55                                       __attr,
56                                       struct sched_param *__restrict __param)
57     ;
58static int (*ppthread_attr_setschedpolicy)(pthread_attr_t *__attr, int __policy)
59     ;
60static int (*ppthread_attr_getschedpolicy)(__const pthread_attr_t *__restrict
61                                        __attr, int *__restrict __policy)
62     ;
63static int (*ppthread_attr_setinheritsched)(pthread_attr_t *__attr,
64                                         int __inherit) ;
65static int (*ppthread_attr_getinheritsched)(__const pthread_attr_t *__restrict
66                                         __attr, int *__restrict __inherit)
67     ;
68static int (*ppthread_attr_setscope)(pthread_attr_t *__attr, int __scope)
69     ;
70static int (*ppthread_attr_getscope)(__const pthread_attr_t *__restrict __attr,
71                                  int *__restrict __scope) ;
72static int (*ppthread_attr_setstackaddr)(pthread_attr_t *__attr,
73                                      void *__stackaddr) ;
74static int (*ppthread_attr_getstackaddr)(__const pthread_attr_t *__restrict
75                                      __attr, void **__restrict __stackaddr)
76     ;
77static int (*ppthread_attr_setstacksize)(pthread_attr_t *__attr,
78                                      size_t __stacksize) ;
79static int (*ppthread_attr_getstacksize)(__const pthread_attr_t *__restrict
80                                      __attr, size_t *__restrict __stacksize)
81     ;
82static int (*ppthread_getattr_np)(pthread_t __th, pthread_attr_t *__attr) ;
83static int (*ppthread_setschedparam)(pthread_t __target_thread, int __policy,
84                                  __const struct sched_param *__param)
85     ;
86static int (*ppthread_getschedparam)(pthread_t __target_thread,
87                                  int *__restrict __policy,
88                                  struct sched_param *__restrict __param)
89     ;
90static int (*ppthread_yield)(void) ;
91static int (*ppthread_mutex_init)(pthread_mutex_t *__restrict __mutex,
92                               __const pthread_mutexattr_t *__restrict
93                               __mutex_attr) ;
94static int (*ppthread_mutex_destroy)(pthread_mutex_t *__mutex) ;
95static int (*ppthread_mutex_trylock)(pthread_mutex_t *__mutex) ;
96static int (*ppthread_mutex_lock)(pthread_mutex_t *__mutex) ;
97static int (*ppthread_mutex_unlock)(pthread_mutex_t *__mutex) ;
98static int (*ppthread_mutexattr_init)(pthread_mutexattr_t *__attr) ;
99static int (*ppthread_mutexattr_destroy)(pthread_mutexattr_t *__attr) ;
100static int (*ppthread_mutexattr_getpshared)(__const pthread_mutexattr_t *
101                                         __restrict __attr,
102                                         int *__restrict __pshared) ;
103static int (*ppthread_mutexattr_setpshared)(pthread_mutexattr_t *__attr,
104                                         int __pshared) ;
105static int (*ppthread_cond_init)(pthread_cond_t *__restrict __cond,
106                              __const pthread_condattr_t *__restrict
107                              __cond_attr) ;
108static int (*ppthread_cond_destroy)(pthread_cond_t *__cond) ;
109static int (*ppthread_cond_signal)(pthread_cond_t *__cond) ;
110static int (*ppthread_cond_broadcast)(pthread_cond_t *__cond) ;
111static int (*ppthread_cond_wait)(pthread_cond_t *__restrict __cond,
112                              pthread_mutex_t *__restrict __mutex);
113static int (*ppthread_cond_timedwait)(pthread_cond_t *__restrict __cond,
114                                   pthread_mutex_t *__restrict __mutex,
115                                   __const struct timespec *__restrict
116                                   __abstime);
117static int (*ppthread_condattr_init)(pthread_condattr_t *__attr) ;
118static int (*ppthread_condattr_destroy)(pthread_condattr_t *__attr) ;
119static int (*ppthread_condattr_getpshared)(__const pthread_condattr_t *
120                                        __restrict __attr,
121                                        int *__restrict __pshared) ;
122static int (*ppthread_condattr_setpshared)(pthread_condattr_t *__attr,
123                                        int __pshared) ;
124static int (*ppthread_key_create)(pthread_key_t *__key,
125                               void (*__destr_function) (void *)) ;
126static int (*ppthread_key_delete)(pthread_key_t __key) ;
127static int (*ppthread_setspecific)(pthread_key_t __key,
128                                __const void *__pointer) ;
129static void *(*ppthread_getspecific)(pthread_key_t __key) ;
130
131static int (*ppthread_once)(pthread_once_t *__once_control,
132                         void (*__init_routine) (void));
133static int (*ppthread_setcancelstate)(int __state, int *__oldstate);
134static int (*ppthread_setcanceltype)(int __type, int *__oldtype);
135static int (*ppthread_cancel)(pthread_t __cancelthread);
136static void (*ppthread_testcancel)(void);
137static void (*_ppthread_cleanup_push)(struct _pthread_cleanup_buffer *__buffer,
138                                   void (*__routine) (void *),
139                                   void *__arg) ;
140static void (*_ppthread_cleanup_pop)(struct _pthread_cleanup_buffer *__buffer,
141                                  int __execute) ;
142static void (*_ppthread_cleanup_push_defer)(struct _pthread_cleanup_buffer *__buffer,
143                                         void (*__routine) (void *),
144                                         void *__arg) ;
145static void (*_ppthread_cleanup_pop_restore)(struct _pthread_cleanup_buffer *__buffer,
146                                          int __execute) ;
147static int (*ppthread_atfork)(void (*__prepare) (void),
148                           void (*__parent) (void),
149                           void (*__child) (void)) ;
150static void (*ppthread_kill_other_threads_np)(void) ;
151static int (*ppthread_kill) (pthread_t thread, int sig);
152
153/***************************************************/
154typedef struct {
155  void *(*cmd) (void *);
156  void *arg;
157  void *array[10];
158  size_t arraysize;
159} threadinfo;
160
161void finish(int loc)
162{
163  ppthread_mutex_lock(&printlock);
164  if(loc < 0) {
165    register void *ebp __asm__ ("ebp");
166    unsigned int stack = (unsigned int)(ebp);
167    for(loc = 0; loc < PSTACK_SIZE; loc++) {
168      if(pstack[loc].used && stack > pstack[loc].start &&
169                             stack < pstack[loc].end) {
170         break;
171      }
172    }
173  }
174  if(loc < PSTACK_SIZE) {
175    fprintf(stderr, "Terminating thread #%d\n", pstack[loc].thread_num);
176    pstack[loc].used = 0;
177  }
178  ppthread_mutex_unlock(&printlock);
179}
180
181static void *thread_stub(void *data) {
182  register void *ebp __asm__ ("ebp");
183  pthread_attr_t attr;
184  unsigned int stack;
185  size_t size;
186  char **strings;
187  char buf[80];
188  time_t t;
189  int loc;
190  void *ret;
191  threadinfo ti = *((threadinfo *)data);
192  free(data);
193  stack = (unsigned int)(ebp) + PTHREAD_OFFSET_MAGIC;
194  ppthread_attr_init(&attr);
195  ppthread_attr_getstacksize(&attr, &size);
196  strings = backtrace_symbols (ti.array, ti.arraysize);
197  time(&t);
198  ctime_r(&t, buf);
199  ppthread_mutex_lock(&printlock);
200  sprintf(printstr, "\nThread #%d: %s%08x: Stack addr=%08x - %08x, size=%08x\n", threadcount++, buf,
201          ppthread_self(), stack-size, stack, size);
202  sprintf(printstr+strlen(printstr), "Obtained %zd stack frames.\n", ti.arraysize);
203  for(loc=0; loc < PSTACK_SIZE; loc++) {
204    if(! pstack[loc].used) {
205       pstack[loc].used = 1;
206       pstack[loc].thread_num = threadcount-1;
207       pstack[loc].start = stack-size;
208       pstack[loc].end = stack;
209       break;
210    }
211  }
212  for (stack = 0; stack < ti.arraysize; stack++) {
213    Dl_info dli;
214    dladdr(ti.array[stack], &dli);
215    //fprintf(stderr, "  name:%s\n  base:%s\n  sname:%s\n  addr: %08x(%08x)\n",
216    //  dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr, ti.array[stack]);
217    sprintf(printstr+strlen(printstr), "%s\n", strings[stack]);
218  }
219  fprintf(stderr, printstr);
220  //write(fd, printstr, strlen(printstr));
221  //fsync(fd);
222  ppthread_mutex_unlock(&printlock);
223  free (strings);
224  ret = ti.cmd(ti.arg);
225  finish(loc);
226  return(ret);
227}
228extern int pthread_create (pthread_t *__restrict __threadp,
229                           __const pthread_attr_t *__restrict __attr,
230                           void *(*__start_routine) (void *),
231                           void *__restrict __arg)  {
232  threadinfo *ti = malloc(sizeof(threadinfo));
233  ti->cmd = __start_routine;
234  ti->arg = __arg;
235  ti->arraysize = backtrace(ti->array, 10);
236  //return ppthread_create(__threadp, __attr, __start_routine, __arg);
237  return ppthread_create(__threadp, __attr, thread_stub, ti);
238}
239extern pthread_t pthread_self (void)  {
240  return ppthread_self();
241}
242
243extern int pthread_equal (pthread_t __thread1, pthread_t __thread2)  {
244  return ppthread_equal(__thread1, __thread2);
245}
246
247extern void pthread_exit (void *__retval) {
248  finish(-1);
249  ppthread_exit(__retval);
250}
251
252extern int pthread_join (pthread_t __th, void **__thread_return) {
253  return ppthread_join(__th, __thread_return);
254}
255
256extern int pthread_detach (pthread_t __th)  {
257  return ppthread_detach(__th);
258}
259
260extern int pthread_attr_init (pthread_attr_t *__attr)  {
261  return ppthread_attr_init(__attr);
262}
263
264extern int pthread_attr_destroy (pthread_attr_t *__attr)  {
265  return ppthread_attr_destroy(__attr);
266}
267
268extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
269                                        int __detachstate)  {
270  return ppthread_attr_setdetachstate(__attr, __detachstate);
271}
272
273extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr,
274                                        int *__detachstate)  {
275  return ppthread_attr_getdetachstate(__attr, __detachstate);
276}
277
278extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
279                                       __const struct sched_param *__restrict
280                                       __param)  {
281  return ppthread_attr_setschedparam(__attr, __param);
282}
283
284extern int pthread_attr_getschedparam (__const pthread_attr_t *__restrict
285                                       __attr,
286                                       struct sched_param *__restrict __param)
287      {
288  return ppthread_attr_getschedparam(__attr, __param);
289}
290
291extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
292      {
293  return ppthread_attr_setschedpolicy(__attr, __policy);
294}
295
296extern int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict
297                                        __attr, int *__restrict __policy)
298      {
299  return ppthread_attr_getschedpolicy(__attr, __policy);
300}
301
302extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
303                                         int __inherit)  {
304  return ppthread_attr_setinheritsched(__attr, __inherit);
305}
306
307extern int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict
308                                         __attr, int *__restrict __inherit)
309      {
310  return ppthread_attr_getinheritsched(__attr, __inherit);
311}
312
313extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
314      {
315  return ppthread_attr_setscope(__attr, __scope);
316}
317
318extern int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr,
319                                  int *__restrict __scope)  {
320  return ppthread_attr_getscope(__attr, __scope);
321}
322
323extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
324                                      void *__stackaddr)  {
325  return ppthread_attr_setstackaddr(__attr, __stackaddr);
326}
327
328extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
329                                      __attr, void **__restrict __stackaddr)
330      {
331  return ppthread_attr_getstackaddr(__attr, __stackaddr);
332}
333
334extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
335                                      size_t __stacksize)  {
336  return ppthread_attr_setstacksize(__attr, __stacksize);
337}
338
339extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict
340                                      __attr, size_t *__restrict __stacksize)
341      {
342  return ppthread_attr_getstacksize(__attr, __stacksize);
343}
344
345extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)  {
346  return ppthread_getattr_np(__th, __attr);
347}
348
349extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
350                                  __const struct sched_param *__param)
351      {
352  return ppthread_setschedparam(__target_thread, __policy, __param);
353}
354
355extern int pthread_getschedparam (pthread_t __target_thread,
356                                  int *__restrict __policy,
357                                  struct sched_param *__restrict __param)
358      {
359  return ppthread_getschedparam(__target_thread, __policy, __param);
360}
361
362extern int pthread_yield (void)  {
363  return ppthread_yield();
364}
365
366extern int pthread_mutex_init (pthread_mutex_t *__restrict __mutex,
367                               __const pthread_mutexattr_t *__restrict
368                               __mutex_attr)  {
369  return ppthread_mutex_init(__mutex, __mutex_attr);
370}
371
372extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)  {
373  return ppthread_mutex_destroy(__mutex);
374}
375
376extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)  {
377  return ppthread_mutex_trylock(__mutex);
378}
379
380extern int pthread_mutex_lock (pthread_mutex_t *__mutex)  {
381  return ppthread_mutex_lock(__mutex);
382}
383
384extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)  {
385  return ppthread_mutex_unlock(__mutex);
386}
387
388extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr)  {
389  return ppthread_mutexattr_init(__attr);
390}
391
392extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)  {
393  return ppthread_mutexattr_destroy(__attr);
394}
395
396extern int pthread_mutexattr_getpshared (__const pthread_mutexattr_t *
397                                         __restrict __attr,
398                                         int *__restrict __pshared)  {
399  return ppthread_mutexattr_getpshared(__attr, __pshared);
400}
401
402extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
403                                         int __pshared)  {
404  return ppthread_mutexattr_setpshared(__attr, __pshared);
405}
406
407extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
408                              __const pthread_condattr_t *__restrict
409                              __cond_attr)  {
410  return ppthread_cond_init(__cond, __cond_attr);
411}
412
413extern int pthread_cond_destroy (pthread_cond_t *__cond)  {
414  return ppthread_cond_destroy(__cond);
415}
416
417extern int pthread_cond_signal (pthread_cond_t *__cond)  {
418  return ppthread_cond_signal(__cond);
419}
420
421extern int pthread_cond_broadcast (pthread_cond_t *__cond)  {
422  return ppthread_cond_broadcast(__cond);
423}
424
425extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
426                              pthread_mutex_t *__restrict __mutex) {
427  return ppthread_cond_wait(__cond, __mutex);
428}
429
430extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
431                                   pthread_mutex_t *__restrict __mutex,
432                                   __const struct timespec *__restrict
433                                   __abstime) {
434  return ppthread_cond_timedwait(__cond, __mutex, __abstime);
435}
436
437extern int pthread_condattr_init (pthread_condattr_t *__attr)  {
438  return ppthread_condattr_init(__attr);
439}
440
441extern int pthread_condattr_destroy (pthread_condattr_t *__attr)  {
442  return ppthread_condattr_destroy(__attr);
443}
444
445extern int pthread_condattr_getpshared (__const pthread_condattr_t *
446                                        __restrict __attr,
447                                        int *__restrict __pshared)  {
448  return ppthread_condattr_getpshared(__attr, __pshared);
449}
450
451extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
452                                        int __pshared)  {
453  return ppthread_condattr_setpshared(__attr, __pshared);
454}
455
456extern int pthread_key_create (pthread_key_t *__key,
457                               void (*__destr_function) (void *))  {
458  return ppthread_key_create(__key, __destr_function);
459}
460
461extern int pthread_key_delete (pthread_key_t __key)  {
462  return ppthread_key_delete(__key);
463}
464
465extern int pthread_setspecific (pthread_key_t __key,
466                                __const void *__pointer)  {
467  return ppthread_setspecific(__key, __pointer);
468}
469
470extern void *pthread_getspecific (pthread_key_t __key)  {
471  return ppthread_getspecific(__key);
472}
473
474extern int pthread_once (pthread_once_t *__once_control,
475                         void (*__init_routine) (void)) {
476  return ppthread_once(__once_control, __init_routine);
477}
478
479extern int pthread_setcancelstate (int __state, int *__oldstate) {
480  return ppthread_setcancelstate(__state, __oldstate);
481}
482
483extern int pthread_setcanceltype (int __type, int *__oldtype) {
484  return ppthread_setcanceltype(__type, __oldtype);
485}
486
487extern int pthread_cancel (pthread_t __cancelthread) {
488  return ppthread_cancel(__cancelthread);
489}
490
491extern void pthread_testcancel (void) {
492  ppthread_testcancel();
493}
494
495extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
496                                   void (*__routine) (void *),
497                                   void *__arg)  {
498  _ppthread_cleanup_push(__buffer, __routine, __arg);
499}
500
501extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
502                                  int __execute)  {
503  _ppthread_cleanup_pop(__buffer, __execute);
504}
505
506extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
507                                         void (*__routine) (void *),
508                                         void *__arg)  {
509  _ppthread_cleanup_push_defer(__buffer, __routine, __arg);
510}
511
512extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
513                                          int __execute)  {
514  _ppthread_cleanup_pop_restore(__buffer, __execute);
515}
516
517extern int pthread_atfork (void (*__prepare) (void),
518                           void (*__parent) (void),
519                           void (*__child) (void))  {
520  return ppthread_atfork(__prepare, __parent, __child);
521}
522
523extern void pthread_kill_other_threads_np (void)  {
524  ppthread_kill_other_threads_np();
525}
526
527extern int pthread_kill(pthread_t thread, int sig) {
528  return ppthread_kill(thread, sig);
529}
530int __attribute__((constructor)) __init(void)
531{
532  void *handle;
533  handle = dlopen(LIBPTHREAD_SO, RTLD_LAZY | RTLD_LOCAL);
534  if(!handle) {
535    fputs("Failed:\n", stderr);
536    fputs(dlerror(), stderr);
537    fputs("\n", stderr);
538    exit(1);
539  }
540  ppthread_create = dlsym(handle,"pthread_create");
541  ppthread_self = dlsym(handle,"pthread_self");
542  ppthread_equal = dlsym(handle,"pthread_equal");
543  ppthread_exit = dlsym(handle,"pthread_exit");
544  ppthread_join = dlsym(handle,"pthread_join");
545  ppthread_detach = dlsym(handle,"pthread_detach");
546  ppthread_attr_init = dlsym(handle,"pthread_attr_init");
547  ppthread_attr_destroy = dlsym(handle,"pthread_attr_destroy");
548  ppthread_attr_setdetachstate = dlsym(handle,"pthread_attr_setdetachstate");
549  ppthread_attr_getdetachstate = dlsym(handle,"pthread_attr_getdetachstate");
550  ppthread_attr_setschedparam = dlsym(handle,"pthread_attr_setschedparam");
551  ppthread_attr_getschedparam = dlsym(handle,"pthread_attr_getschedparam");
552  ppthread_attr_setschedpolicy = dlsym(handle,"pthread_attr_setschedpolicy");
553  ppthread_attr_getschedpolicy = dlsym(handle,"pthread_attr_getschedpolicy");
554  ppthread_attr_setinheritsched = dlsym(handle,"pthread_attr_setinheritsched");
555  ppthread_attr_getinheritsched = dlsym(handle,"pthread_attr_getinheritsched");
556  ppthread_attr_setscope = dlsym(handle,"pthread_attr_setscope");
557  ppthread_attr_getscope = dlsym(handle,"pthread_attr_getscope");
558  ppthread_attr_setstackaddr = dlsym(handle,"pthread_attr_setstackaddr");
559  ppthread_attr_getstackaddr = dlsym(handle,"pthread_attr_getstackaddr");
560  ppthread_attr_setstacksize = dlsym(handle,"pthread_attr_setstacksize");
561  ppthread_attr_getstacksize = dlsym(handle,"pthread_attr_getstacksize");
562  ppthread_getattr_np = dlsym(handle,"pthread_getattr_np");
563  ppthread_setschedparam = dlsym(handle,"pthread_setschedparam");
564  ppthread_getschedparam = dlsym(handle,"pthread_getschedparam");
565  ppthread_yield = dlsym(handle,"pthread_yield");
566  ppthread_mutex_init = dlsym(handle,"pthread_mutex_init");
567  ppthread_mutex_destroy = dlsym(handle,"pthread_mutex_destroy");
568  ppthread_mutex_trylock = dlsym(handle,"pthread_mutex_trylock");
569  ppthread_mutex_lock = dlsym(handle,"pthread_mutex_lock");
570  ppthread_mutex_unlock = dlsym(handle,"pthread_mutex_unlock");
571  ppthread_mutexattr_init = dlsym(handle,"pthread_mutexattr_init");
572  ppthread_mutexattr_destroy = dlsym(handle,"pthread_mutexattr_destroy");
573  ppthread_mutexattr_getpshared = dlsym(handle,"pthread_mutexattr_getpshared");
574  ppthread_mutexattr_setpshared = dlsym(handle,"pthread_mutexattr_setpshared");
575  ppthread_cond_init = dlsym(handle,"pthread_cond_init");
576  ppthread_cond_destroy = dlsym(handle,"pthread_cond_destroy");
577  ppthread_cond_signal = dlsym(handle,"pthread_cond_signal");
578  ppthread_cond_broadcast = dlsym(handle,"pthread_cond_broadcast");
579  ppthread_cond_wait = dlsym(handle,"pthread_cond_wait");
580  ppthread_cond_timedwait = dlsym(handle,"pthread_cond_timedwait");
581  ppthread_condattr_init = dlsym(handle,"pthread_condattr_init");
582  ppthread_condattr_destroy = dlsym(handle,"pthread_condattr_destroy");
583  ppthread_condattr_getpshared = dlsym(handle,"pthread_condattr_getpshared");
584  ppthread_condattr_setpshared = dlsym(handle,"pthread_condattr_setpshared");
585  ppthread_key_create = dlsym(handle,"pthread_key_create");
586  ppthread_key_delete = dlsym(handle,"pthread_key_delete");
587  ppthread_setspecific = dlsym(handle,"pthread_setspecific");
588  ppthread_getspecific = dlsym(handle,"pthread_getspecific");
589  ppthread_once = dlsym(handle,"pthread_once");
590  ppthread_setcancelstate = dlsym(handle,"pthread_setcancelstate");
591  ppthread_setcanceltype = dlsym(handle,"pthread_setcanceltype");
592  ppthread_cancel = dlsym(handle,"pthread_cancel");
593  ppthread_testcancel = dlsym(handle,"pthread_testcancel");
594  _ppthread_cleanup_push = dlsym(handle,"_pthread_cleanup_push");
595  _ppthread_cleanup_pop = dlsym(handle,"_pthread_cleanup_pop");
596  _ppthread_cleanup_push_defer = dlsym(handle,"_pthread_cleanup_push_defer");
597  _ppthread_cleanup_pop_restore = dlsym(handle,"_pthread_cleanup_pop_restore");
598  ppthread_atfork = dlsym(handle,"pthread_atfork");
599  ppthread_kill_other_threads_np = dlsym(handle,"pthread_kill_other_threads_np");
600  ppthread_kill = dlsym(handle, "pthread_kill");
601  if(0) {
602    int i = getpid();
603    char filename[80];
604    char str[80];
605    sprintf(filename, "/tmp/pthreaddbg.%d", i);
606    fd = open(filename, O_CREAT | O_TRUNC, 0666);
607    if(fd == -1) { exit(-1);}
608    sprintf(str, "Beginning pthread debug\n");
609    write(fd, str, strlen(str));
610  }
611  pstack = (struct pstack_t *)calloc(PSTACK_SIZE,sizeof(struct pstack_t));
612  return 0;
613}