Fix valgrind found error of uninitialized data in thread_db with ProcControlAPI
[dyninst.git] / proccontrol / src / int_thread_db.C
1 /*
2  * Copyright (c) 1996-2011 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "common/h/Types.h"
33 #include "proccontrol/src/int_thread_db.h"
34
35 #if defined(cap_thread_db)
36
37 #include <cassert>
38 #include <cerrno>
39 #include <cstdarg>
40 #include <cstring>
41 #include <set>
42 #include <dlfcn.h>
43
44 using namespace std;
45
46 #include "common/h/dthread.h"
47 #include "dynutil/h/SymReader.h"
48 #include "proccontrol/src/int_event.h"
49
50 /* 
51  * proc_service interface implementation, needed by libthread_db
52  */
53
54 ps_err_e ps_pglobal_lookup(struct ps_prochandle *handle, const char *objName, 
55         const char *symName, psaddr_t *symbolAddr)
56 {
57     pthrd_printf("Looking up symbol %s in %s\n", symName, objName);
58     return handle->thread_db_proc->getSymbolAddr(objName, symName, symbolAddr);
59 }
60
61 ps_err_e ps_pread(struct ps_prochandle *handle, psaddr_t remote, void *local, size_t size) {
62    thread_db_process *llproc = handle->thread_db_proc;
63    pthrd_printf("thread_db reading from %#lx to %#lx, size = %d on %d\n",
64                 (unsigned long)remote, (unsigned long)local, (int)size, llproc->getPid());
65
66    llproc->resps.clear();
67    async_ret_t result = llproc->getMemCache()->readMemory(local, (Address) remote, size,
68                                                           llproc->resps,
69                                                           llproc->triggerThread());
70    switch (result) {
71       case aret_success:
72          llproc->hasAsyncPending = false;
73          return PS_OK;
74       case aret_async:
75          llproc->hasAsyncPending = true;
76          pthrd_printf("Incomplete async read in thread_db read\n");
77          return PS_ERR;
78       case aret_error:
79          llproc->hasAsyncPending = false;
80          pthrd_printf("Unexpected read error in thread_db read\n");
81          return PS_ERR;
82    }
83    assert(0);
84    return PS_ERR;
85 }
86
87 ps_err_e ps_pdread(struct ps_prochandle *handle, psaddr_t remote, void *local, size_t size) {
88    return ps_pread(handle, remote, local, size);
89 }
90
91 ps_err_e ps_ptread(struct ps_prochandle *handle, psaddr_t remote, void *local, size_t size) {
92    return ps_pread(handle, remote, local, size);
93 }
94
95 ps_err_e ps_pwrite(struct ps_prochandle *handle, psaddr_t remote, const void *local, size_t size) {
96     pthrd_printf("thread_db writing to %#lx from %#lx, size = %d on %d\n",
97             (unsigned long)remote, (unsigned long)local, (int)size, handle->thread_db_proc->getPid());
98
99     thread_db_process *proc = handle->thread_db_proc;
100
101     async_ret_t result = proc->getMemCache()->writeMemory((Address) remote, 
102                                                           const_cast<void *>(local), 
103                                                           size, 
104                                                           proc->res_resps, 
105                                                           proc->triggerThread());
106     switch (result) {
107       case aret_success:
108          proc->hasAsyncPending = false;
109          return PS_OK;
110       case aret_async:
111          proc->hasAsyncPending = true;
112          pthrd_printf("Incomplete async write in thread_db write\n");
113          return PS_ERR;
114       case aret_error:
115          proc->hasAsyncPending = false;
116          pthrd_printf("Unexpected read error in thread_db write\n");
117          return PS_ERR;
118     }
119     assert(0);
120     return PS_ERR;
121 }
122
123 ps_err_e ps_pdwrite(struct ps_prochandle *handle, psaddr_t remote, const void *local, size_t size) {
124    return ps_pwrite(handle, remote, local, size);
125 }
126
127 ps_err_e ps_ptwrite(struct ps_prochandle *handle, psaddr_t remote, const void *local, size_t size) {
128    return ps_pwrite(handle, remote, local, size);
129 }
130
131 ps_err_e ps_linfo(struct ps_prochandle *handle, lwpid_t lwp, void *lwpInfo) {
132     if( !handle->thread_db_proc->plat_getLWPInfo(lwp, lwpInfo) )
133         return PS_ERR;
134
135     return PS_OK;
136 }
137
138 ps_err_e ps_lstop(struct ps_prochandle *handle, lwpid_t lwp) {
139    int_process *proc = handle->thread_db_proc;
140    int_threadPool *tp = proc->threadPool();
141    assert(tp);
142    int_thread *thr = tp->findThreadByLWP((Dyninst::LWP) lwp);
143    if (!thr) {
144       perr_printf("ps_lstop is unable to find LWP %d in process %d\n",
145                   lwp, proc->getPid());
146       return PS_ERR;
147    }
148    pthrd_printf("ps_lstop on %d/%d\n", proc->getPid(), thr->getLWP());
149    
150    if (thr->getInternalState().getState() == int_thread::stopped) {
151       return PS_OK;
152    }
153    else if (thr->getInternalState().getState() != int_thread::running) {
154       perr_printf("Error, ps_lstop on thread in bad state\n");
155       return PS_ERR;
156    }
157
158    thr->getInternalState().setState(int_thread::stopped);
159    
160    return PS_OK;
161 }
162
163 ps_err_e ps_lcontinue(struct ps_prochandle *handle, lwpid_t lwp) {
164    int_process *proc = handle->thread_db_proc;
165    int_threadPool *tp = proc->threadPool();
166    assert(tp);
167    int_thread *thr = tp->findThreadByLWP((Dyninst::LWP) lwp);
168    if (!thr) {
169       perr_printf("ps_lcontinue is unable to find LWP %d in process %d\n",
170                   lwp, proc->getPid());
171       return PS_ERR;
172    }
173    pthrd_printf("ps_lcontinue on %d/%d\n", proc->getPid(), thr->getLWP());
174    
175    if (thr->getInternalState().getState() == int_thread::running) {
176       return PS_OK;
177    }
178    else if (thr->getInternalState().getState() != int_thread::stopped) {
179       perr_printf("Error, ps_lcontinue on thread in bad state\n");
180       return PS_ERR;
181    }
182    
183    thr->getInternalState().setState(int_thread::stopped);
184    return PS_OK;
185 }
186
187 ps_err_e ps_lgetregs(struct ps_prochandle *handle, lwpid_t lwp, prgregset_t regs) {
188    thread_db_process *proc = handle->thread_db_proc;
189    int_threadPool *tp = proc->threadPool();
190    assert(tp);
191    int_thread *llthr = tp->findThreadByLWP((Dyninst::LWP) lwp);
192    if (!llthr) {
193       perr_printf("ps_lgetregs is unable to find LWP %d in process %d\n",
194                   lwp, proc->getPid());
195       return PS_ERR;
196    }
197
198    thread_db_thread *thr = dynamic_cast<thread_db_thread *>(llthr);
199    
200    pthrd_printf("thread_db reading registers on thread %d/%d\n",
201                 proc->getPid(), thr->getLWP());
202    
203    int_registerPool pool;
204    async_ret_t result = proc->getMemCache()->getRegisters(llthr, pool);
205    if (result == aret_async) {
206       pthrd_printf("Async return during get reg\n");
207       return PS_ERR;
208    }
209    if (result == aret_error) {
210       pthrd_printf("Error return during get reg\n");
211       return PS_ERR;
212    }
213
214    bool bresult = thr->plat_convertToSystemRegs(pool, (unsigned char *) regs);
215    if (!bresult) {
216       pthrd_printf("Error convering to system regs\n");
217       return PS_ERR;
218    }
219    return PS_OK;
220 }
221
222 pid_t ps_getpid (struct ps_prochandle *ph)
223 {
224    return ph->thread_db_proc->getPid();
225 }
226
227 void ps_plog(const char *format, ...) {
228     if( !dyninst_debug_proccontrol ) return;
229     if( NULL == format ) return;
230
231     va_list va;
232     va_start(va, format);
233     vfprintf(pctrl_err_out, format, va);
234     va_end(va);
235 }
236
237 #define NA_IMPLEMENTED "This function is not implemented"
238
239 ps_err_e ps_lgetfpregs(struct ps_prochandle *, lwpid_t, prfpregset_t *) {
240     assert(!NA_IMPLEMENTED);
241     return PS_ERR;
242 }
243
244 ps_err_e ps_lsetfpregs(struct ps_prochandle *, lwpid_t, const prfpregset_t *) {
245     assert(!NA_IMPLEMENTED);
246     return PS_ERR;
247 }
248
249 ps_err_e ps_lsetregs(struct ps_prochandle *, lwpid_t, const prgregset_t) {
250     assert(!NA_IMPLEMENTED);
251     return PS_ERR;
252 }
253
254 ps_err_e ps_lgetxmmregs (struct ps_prochandle *, lwpid_t, char *) {
255     assert(!NA_IMPLEMENTED);
256     return PS_ERR;
257 }
258
259 ps_err_e ps_lsetxmmregs (struct ps_prochandle *, lwpid_t, const char *) {
260     assert(!NA_IMPLEMENTED);
261     return PS_ERR;
262 }
263
264 ps_err_e ps_pcontinue(struct ps_prochandle *) {
265     assert(!NA_IMPLEMENTED);
266     return PS_ERR;
267 }
268
269 ps_err_e ps_pdmodel(struct ps_prochandle *, int *) {
270     assert(!NA_IMPLEMENTED);
271     return PS_ERR;
272 }
273
274 ps_err_e ps_pstop(struct ps_prochandle *) {
275     assert(!NA_IMPLEMENTED);
276     return PS_ERR;
277 }
278
279 ps_err_e ps_get_thread_area(const struct ps_prochandle *phandle, lwpid_t lwp, int val, psaddr_t *addr)
280 {
281    thread_db_process *tdb_proc = phandle->thread_db_proc;
282    thread_db_thread *tdb_thread = dynamic_cast<thread_db_thread *>(tdb_proc->threadPool()->findThreadByLWP(lwp));
283
284    Dyninst::Address daddr = 0;
285    bool result = tdb_thread->thrdb_getThreadArea(val, daddr);
286    if (addr && result)
287       *addr = (psaddr_t) daddr;
288       
289    return result ? PS_OK : PS_ERR;
290 }
291
292 #if defined(THREAD_DB_STATIC)
293 #define TDB_BIND(SYM) \
294    p_ ## SYM = SYM
295 #else
296 #define TDB_BIND(SYM) \
297    do { \
298      p_ ## SYM = (SYM ## _t) dlsym(libhandle, #SYM); \
299      if (!p_ ## SYM) { \
300        const char *errmsg = dlerror();                                       \
301        perr_printf("Error looking up %s in threaddb.so: %s\n", #SYM, errmsg); \
302        return false; \
303      } \
304    } while (0)
305 #endif
306
307 #if defined(THREAD_DB_PATH)
308 #define THREAD_DB_PATH_STR THREAD_DB_PATH
309 #else
310 #define THREAD_DB_PATH_STR NULL
311 #endif
312
313 thread_db_process::td_init_t thread_db_process::p_td_init;
314 thread_db_process::td_ta_new_t thread_db_process::p_td_ta_new;
315 thread_db_process::td_ta_delete_t thread_db_process::p_td_ta_delete;
316 thread_db_process::td_ta_event_addr_t thread_db_process::p_td_ta_event_addr;
317 thread_db_process::td_ta_set_event_t thread_db_process::p_td_ta_set_event;
318 thread_db_process::td_ta_map_lwp2thr_t thread_db_process::p_td_ta_map_lwp2thr;
319 thread_db_process::td_ta_event_getmsg_t thread_db_process::p_td_ta_event_getmsg;
320 thread_db_process::td_thr_get_info_t thread_db_process::p_td_thr_get_info;
321 thread_db_process::td_thr_event_enable_t thread_db_process::p_td_thr_event_enable;
322 thread_db_process::td_thr_set_event_t thread_db_process::p_td_thr_set_event;
323 thread_db_process::td_thr_event_getmsg_t thread_db_process::p_td_thr_event_getmsg;
324 thread_db_process::td_thr_dbsuspend_t thread_db_process::p_td_thr_dbsuspend;
325 thread_db_process::td_thr_dbresume_t thread_db_process::p_td_thr_dbresume;
326
327 bool thread_db_process::tdb_loaded = false;
328 bool thread_db_process::tdb_loaded_result = false;
329
330 #if !defined(THREAD_DB_STATIC)
331 static void *dlopenThreadDB(char *path)
332 {
333    std::string filename;
334    std::string alt_filename;
335    if (path) {
336       filename = std::string(path);
337       if (*filename.rend() != '/') {
338          filename += std::string("/");
339       }
340       filename += std::string("libthread_db.so");
341 #if !defined(os_bg)
342       //On BG alt_filename would try to load /lib/libthread_db.so, which is
343       // for the IO node.
344       alt_filename = std::string("libthread_db.so");
345 #endif
346
347    }
348    else {
349       filename = std::string("libthread_db.so");
350    }
351
352 #if defined(os_bgq)
353    alt_filename = filename;
354    filename = std::string("/bgsys/drivers/ppcfloor/gnu-linux/powerpc64-bgq-linux/lib/libthread_db.so.1");
355 #endif
356
357    pthrd_printf("Opening thread_db with %s\n", filename.c_str());
358    void *libhandle = dlopen(filename.c_str(), RTLD_LAZY);
359    if (!libhandle && !alt_filename.empty()) {
360    pthrd_printf("Opening thread_db with %s\n", alt_filename.c_str());
361       libhandle = dlopen(alt_filename.c_str(), RTLD_LAZY);
362    }
363    if (!libhandle) {
364       const char *errmsg = dlerror();
365       perr_printf("Error loading libthread_db.so: %s\n", errmsg);
366       return NULL;
367    }
368    return libhandle;
369 }
370
371 #else
372 static void *dlopenThreadDB(char *)
373 {
374    return (void *) 0x1;  //Return anything non-NULL
375 }
376 #endif
377
378 bool thread_db_process::loadedThreadDBLibrary()
379 {
380    if (tdb_loaded)
381       return tdb_loaded_result;
382    tdb_loaded = true;
383    
384    void *libhandle = dlopenThreadDB(THREAD_DB_PATH_STR);
385    if (!libhandle)
386       return false;
387
388    TDB_BIND(td_init);
389    TDB_BIND(td_ta_new);
390    TDB_BIND(td_ta_delete);
391    TDB_BIND(td_ta_event_addr);
392    TDB_BIND(td_ta_set_event);
393    TDB_BIND(td_ta_event_getmsg);
394    TDB_BIND(td_ta_map_lwp2thr);
395    TDB_BIND(td_thr_get_info);
396    TDB_BIND(td_thr_event_enable);
397    TDB_BIND(td_thr_set_event);
398    TDB_BIND(td_thr_event_getmsg);
399    TDB_BIND(td_thr_dbsuspend);
400    TDB_BIND(td_thr_dbresume);
401
402    pthrd_printf("Successfully loaded thread_db.so library\n");
403    tdb_loaded_result = true;
404    return true;
405 }
406
407 #ifndef CASE_RETURN_STR
408 #define CASE_RETURN_STR(x) case x: return #x;
409 #endif
410
411 static const char *tdErr2Str(td_err_e errVal) {
412     switch(errVal) {
413         CASE_RETURN_STR(TD_ERR)
414         CASE_RETURN_STR(TD_OK)
415         CASE_RETURN_STR(TD_BADKEY)
416         CASE_RETURN_STR(TD_BADPH)
417         CASE_RETURN_STR(TD_BADSH)
418         CASE_RETURN_STR(TD_BADTA)
419         CASE_RETURN_STR(TD_BADTH)
420         CASE_RETURN_STR(TD_DBERR)
421         CASE_RETURN_STR(TD_MALLOC)
422         CASE_RETURN_STR(TD_NOAPLIC)
423         CASE_RETURN_STR(TD_NOCAPAB)
424         CASE_RETURN_STR(TD_NOEVENT)
425         CASE_RETURN_STR(TD_NOFPREGS)
426         CASE_RETURN_STR(TD_NOLIBTHREAD)
427         CASE_RETURN_STR(TD_NOLWP)
428         CASE_RETURN_STR(TD_NOMSG)
429         CASE_RETURN_STR(TD_NOSV)
430         CASE_RETURN_STR(TD_NOTHR)
431         CASE_RETURN_STR(TD_NOTSD)
432         CASE_RETURN_STR(TD_NOXREGS)
433         CASE_RETURN_STR(TD_PARTIALREG)
434         default:
435             return "?";
436     }
437 }
438
439 Event::ptr thread_db_process::decodeThreadEvent(td_event_msg_t *eventMsg, bool &async)
440 {
441    td_thrinfo_t info;
442    async = false;
443    async_ret_t result = ll_fetchThreadInfo(const_cast<td_thrhandle_t *>(eventMsg->th_p), &info);
444    if (result == aret_error) {
445       pthrd_printf("Failed to fetch thread info\n");
446       return Event::ptr();
447    }
448    if (result == aret_async) {
449       async = true;
450       pthrd_printf("Returning async from decodeThreadEvent\n");
451       return Event::ptr();
452    }
453    Dyninst::LWP lwp = (Dyninst::LWP) info.ti_lid;
454    int_thread *thr = threadPool()->findThreadByLWP(lwp); //thr may be NULL if OS doesn't support LWP events (BG/P) 
455    switch(eventMsg->event) {
456       case TD_CREATE:
457       {
458          pthrd_printf("Decoded to user thread create of %d/%d\n", getPid(), lwp);
459
460          EventNewUserThread::ptr new_ev = EventNewUserThread::ptr(new EventNewUserThread());
461          new_ev->setProcess(proc());
462          new_ev->setThread(thr ? thr->thread() : Thread::ptr());
463          new_ev->setSyncType(Event::sync_process);
464          int_eventNewUserThread *iev = new_ev->getInternalEvent();
465
466          new_thread_data_t *thrdata = (new_thread_data_t *) malloc(sizeof(new_thread_data_t));
467          thrdata->thr_handle = new td_thrhandle_t(*(eventMsg->th_p));
468          thrdata->thr_info = info;
469          thrdata->threadHandle_alloced = true;
470
471          iev->raw_data = (void *) thrdata;
472          iev->lwp = lwp;
473
474          if (threadPool()->initialThread() == thr)
475             initialThreadEventCreated = true;
476
477          return new_ev;
478       }
479       case TD_DEATH: {
480          pthrd_printf("Decoded to user thread death of %d/%d\n", getPid(), lwp);
481          if (!thr) {
482             perr_printf("Error.  Got thread delete event for unknown LWP\n");
483             return Event::ptr();
484          }
485
486          EventUserThreadDestroy::ptr new_ev = EventUserThreadDestroy::ptr(new EventUserThreadDestroy(EventType::Pre));
487          new_ev->setProcess(proc());
488          new_ev->setThread(thr->thread());
489          new_ev->setSyncType(Event::sync_thread);
490
491          return new_ev;
492       }
493       default: {
494          pthrd_printf("Unimplemented libthread_db event encountered. Skipping for now.\n");
495          break;
496       }
497    }
498
499    return Event::ptr();
500 }
501
502 volatile bool thread_db_process::thread_db_initialized = false;
503 Mutex thread_db_process::thread_db_init_lock;
504
505 thread_db_process::thread_db_process(Dyninst::PID p, std::string e, std::vector<std::string> envp, std::vector<std::string> a, std::map<int, int> f) :
506   int_process(p, e, a, envp, f),
507   thread_db_proc_initialized(false),
508   threadAgent(NULL),
509   createdThreadAgent(false),
510   self(NULL),
511   trigger_thread(NULL),
512   initialThreadEventCreated(false),
513   setEventSet(false),
514   completed_post(false)
515 {
516    if (!loadedThreadDBLibrary())
517       return;
518    self = new ps_prochandle();
519    assert(self);
520    self->thread_db_proc = this;
521 }
522
523 thread_db_process::thread_db_process(Dyninst::PID pid_, int_process *p) :
524   int_process(pid_, p), 
525   thread_db_proc_initialized(false),
526   threadAgent(NULL),
527   createdThreadAgent(false),
528   self(NULL),
529   trigger_thread(NULL),
530   initialThreadEventCreated(false),
531   setEventSet(false),
532   completed_post(false)
533 {
534    if (!loadedThreadDBLibrary())
535       return;
536    self = new ps_prochandle();
537    assert(self);
538    self->thread_db_proc = this;
539 }
540
541 thread_db_process::~thread_db_process() 
542 {
543     // Free the breakpoints allocated for events
544     map<Dyninst::Address, pair<int_breakpoint *, EventType> >::iterator brkptIter;
545     for(brkptIter = addr2Event.begin(); brkptIter != addr2Event.end(); ++brkptIter) {
546         delete brkptIter->second.first;
547     }
548
549     delete self;
550 }
551
552 async_ret_t thread_db_process::initThreadWithHandle(td_thrhandle_t *thr, td_thrinfo_t *info, LWP lwp)
553 {
554    pthrd_printf("initThreadWithHandle on %d/%d\n", getPid(), lwp);
555
556    td_thrinfo_t tinfo;
557    if (!info) {
558       async_ret_t result = ll_fetchThreadInfo(thr, &tinfo);
559       if (result == aret_error) {
560          pthrd_printf("Error calling ll_fetchThreadInfo from initThreadWithHandle\n");
561          return aret_error;
562       }
563       if (result == aret_async) {
564          pthrd_printf("Returning async from initThreadWithHandle\n");
565          return aret_async;
566       }
567       info = &tinfo;
568    }
569
570    if (lwp == NULL_LWP) {
571       lwp = (Dyninst::LWP) info->ti_lid;
572       pthrd_printf("initThreadWithHandle found thread %d/%d\n", getPid(), lwp);
573    }
574    thread_db_thread *tdb_thread = dynamic_cast<thread_db_thread *>(threadPool()->findThreadByLWP(lwp));
575    if (!tdb_thread) {
576       perr_printf("Error.  Thread_db reports thread %d/%d, but couldn't find existing LWP\n",
577                   getPid(), lwp);
578       return aret_error;
579    }
580    if (tdb_thread->thread_initialized) {
581       return aret_success;
582    }
583    pthrd_printf("thread_db handling thread create for %d/%d\n", getPid(), lwp);
584    tdb_thread->threadHandle = thr;
585    tdb_thread->tinfo = *info;
586    if (info->ti_tid)
587       tdb_thread->tinfo_initialized = true;
588
589    getMemCache()->markToken(token_seteventreporting);
590    async_ret_t result = tdb_thread->setEventReporting(true);
591    if (result == aret_error) {
592       pthrd_printf("Error in setEventReporting for %d/%d\n", getPid(), tdb_thread->getLWP());
593       return aret_error;
594    }
595    if (result == aret_async) {
596       pthrd_printf("Async return in setEventReporting for %d/%d\n", getPid(), tdb_thread->getLWP());
597       return aret_async;
598    }
599    getMemCache()->condense();
600    tdb_thread->thread_initialized = true;
601    return aret_success;
602 }
603
604
605 async_ret_t thread_db_process::handleThreadAttach(td_thrhandle_t *thr, Dyninst::LWP lwp)
606 {
607    return initThreadWithHandle(thr, NULL, lwp);
608 }
609
610 async_ret_t thread_db_process::initThreadDB() {
611     // Q: Why isn't this in the constructor? 
612     // A: This function depends on the corresponding thread library being loaded
613     // and this event occurs some time after process creation.
614
615     // Make sure thread_db is initialized - only once for all instances
616    if( !thread_db_initialized ) {
617       pthrd_printf("Initializing thread_db library\n");
618       thread_db_init_lock.lock();
619       if( !thread_db_initialized ) {
620          if (!loadedThreadDBLibrary()) {
621             setLastError(err_internal, "libthread_db was not loaded");
622             thread_db_init_lock.unlock();
623             return aret_error;
624          }
625          td_err_e errVal;
626          if( TD_OK != (errVal = p_td_init()) ) {
627             perr_printf("Failed to initialize libthread_db: %s(%d)\n",
628                         tdErr2Str(errVal), errVal);
629             setLastError(err_internal, "libthread_db initialization failed");
630             thread_db_init_lock.unlock();
631             return aret_error;
632           }
633          pthrd_printf("Sucessfully initialized thread_db\n");
634          thread_db_initialized = true;
635       }
636       thread_db_init_lock.unlock();
637    }
638    if (thread_db_proc_initialized) {
639       return aret_success;
640    }
641
642    getMemCache()->markToken(token_init);   
643    // Create the thread agent
644    td_err_e errVal;
645    if (!createdThreadAgent)
646    {
647       pthrd_printf("Creating threadAgent\n");
648       errVal = p_td_ta_new(self, &threadAgent);
649       switch(errVal) {
650          case TD_OK:
651             pthrd_printf("Retrieved thread agent from thread_db\n");
652             break;
653          case TD_NOLIBTHREAD:
654             pthrd_printf("Debuggee isn't multithreaded at this point, libthread_db not enabled\n");
655             return aret_success;
656          case TD_ERR:
657             if (getMemCache()->hasPendingAsync()) {
658                pthrd_printf("Postponing thread_db initialization for async\n");
659                return aret_async;
660             }
661          default:
662             perr_printf("Failed to create thread agent: %s(%d)\n",
663                         tdErr2Str(errVal), errVal);
664             thread_db_proc_initialized = true;
665             setLastError(err_internal, "Failed to create libthread_db agent");
666             return aret_error;
667       }
668       createdThreadAgent = true;
669    }
670
671    bool hasAsync = false;
672    set<pair<td_thrhandle_t *, LWP> > all_handles;
673    for (int_threadPool::iterator i = threadPool()->begin(); i != threadPool()->end(); i++) {
674       thread_db_thread *tdb_thread = dynamic_cast<thread_db_thread *>(*i);
675       
676       if (tdb_thread->threadHandle_alloced) {
677          all_handles.insert(pair<td_thrhandle_t *, LWP>(tdb_thread->threadHandle, tdb_thread->getLWP()));
678          continue;
679       }
680       
681       if (!tdb_thread->threadHandle) {
682          tdb_thread->threadHandle = new td_thrhandle_t;
683          memset(tdb_thread->threadHandle, 0, sizeof(td_thrhandle_t));
684       }
685       
686       pthrd_printf("lwp2thr on %d/%d\n", getPid(), tdb_thread->getLWP());
687       errVal = p_td_ta_map_lwp2thr(getThreadDBAgent(), tdb_thread->getLWP(), tdb_thread->threadHandle);
688       if (errVal != TD_OK) {
689          if (getMemCache()->hasPendingAsync()) {
690             pthrd_printf("Hit async during lwp2thr\n");
691             hasAsync = true;
692             continue;
693          }
694          perr_printf("Failed to map LWP %d to thread_db thread: %s(%d)\n",
695                      tdb_thread->getLWP(), tdErr2Str(errVal), errVal);
696          setLastError(err_internal, "Failed to get thread_db thread handle");
697          delete tdb_thread->threadHandle;
698          tdb_thread->threadHandle = NULL;
699          continue;
700       }
701       pthrd_printf("Successful lwp2thr on %d/%d\n", getPid(), tdb_thread->getLWP());
702       tdb_thread->threadHandle_alloced = true;
703       all_handles.insert(pair<td_thrhandle_t *, LWP>(tdb_thread->threadHandle, tdb_thread->getLWP()));
704    }
705    if (hasAsync) {
706       pthrd_printf("Postponing lwp2thr for async\n");
707       return aret_async;
708    }
709
710    pthrd_printf("handleThreadAttach for %d threads\n", (int) all_handles.size());
711    for (set<pair<td_thrhandle_t *, LWP> >::iterator i = all_handles.begin(); i != all_handles.end(); i++)
712    {
713       async_ret_t result = handleThreadAttach(i->first, i->second);
714       if (result == aret_error) {
715          perr_printf("Error handling thread_db attach\n");
716          return aret_error;
717       }
718       if (result == aret_async) {
719          pthrd_printf("handleThreadAttach returned async in initThreadDB\n");
720          return aret_async;
721       }
722    }
723    
724    // Enable all events
725    td_thr_events_t eventMask;
726 #if defined(td_event_fillset)
727    //Macro on GNU libc
728    td_event_fillset(&eventMask);
729 #elif defined(os_freebsd)
730    //Inline header file function on FreeBSD
731    td_event_fillset(&eventMask);
732 #else
733 //Need to make td_event_fillset a function pointer if this hits
734 #error td_event_fillset is not a macro on this platform
735 #endif
736
737    if (!setEventSet) {
738       getMemCache()->markToken(token_setevent);
739       errVal = p_td_ta_set_event(threadAgent, &eventMask);
740       if( errVal != TD_OK && getMemCache()->hasPendingAsync()) {
741          pthrd_printf("Async return from td_ta_set_event in initThreadDB\n");
742          return aret_async;
743       }
744       setEventSet = true;
745       getMemCache()->condense();
746       if (errVal != TD_OK) {
747          perr_printf("Failed to enable events: %s(%d)\n",
748                      tdErr2Str(errVal), errVal);
749          setLastError(err_internal, "Failed to enable libthread_db events");
750          thread_db_proc_initialized = true;
751          return aret_error;
752       }
753    }
754
755     // Determine the addresses for all events
756    td_event_e allEvents[] = { TD_CATCHSIG, TD_CONCURRENCY, TD_CREATE,
757                               TD_DEATH, TD_IDLE, TD_LOCK_TRY, TD_PREEMPT, TD_PRI_INHERIT,
758                               TD_READY, TD_REAP, TD_SLEEP, TD_SWITCHFROM, TD_SWITCHTO,
759                               TD_TIMEOUT };
760
761    for(unsigned i = 0; i < (sizeof(allEvents)/sizeof(td_event_e)); ++i) {
762       td_notify_t notifyResult;
763       errVal = p_td_ta_event_addr(threadAgent, allEvents[i], &notifyResult);
764       
765       // This indicates that the event isn't supported
766       if( TD_OK != errVal ) continue;
767       
768       assert( notifyResult.type == NOTIFY_BPT && "Untested notify type" );
769       
770       EventType newEvent;
771       switch(allEvents[i]) {
772          case TD_CREATE:
773             newEvent = EventType(EventType::Post, EventType::ThreadCreate);
774             pthrd_printf("Installing breakpoint for thread creation events\n");
775             break;
776          case TD_DEATH:
777             newEvent = EventType(EventType::Post, EventType::ThreadDestroy);
778             pthrd_printf("Installing breakpoint for thread destroy events\n");
779             break;
780          default:
781             pthrd_printf("Unimplemented libthread_db event encountered. Skipping for now.\n");
782             continue;
783       }
784       
785       Address addr = (Address) notifyResult.u.bptaddr;
786       if( !plat_convertToBreakpointAddress(addr, triggerThread()) ) {
787          perr_printf("Failed to determine breakpoint address\n");
788          setLastError(err_internal, "Failed to install new thread_db event breakpoint");
789          thread_db_proc_initialized = true;
790          return aret_error;
791       }
792       notifyResult.u.bptaddr = (void *) addr;
793       
794       int_breakpoint *newEventBrkpt = new int_breakpoint(Breakpoint::ptr());
795       newEventBrkpt->setProcessStopper(true);
796       if( !addBreakpoint(addr, newEventBrkpt))
797       {
798          perr_printf("Failed to install new event breakpoint\n");
799          setLastError(err_internal, "Failed to install new thread_db event breakpoint");
800          delete newEventBrkpt;
801          thread_db_proc_initialized = true;
802          return aret_error;
803          }
804       
805       pair<map<Dyninst::Address, pair<int_breakpoint *, EventType> >::iterator, bool> insertIter;
806       insertIter = addr2Event.insert(make_pair(addr, make_pair(newEventBrkpt, newEvent)));
807
808       assert( insertIter.second && "event breakpoint address not unique" );
809    }
810    
811    thread_db_proc_initialized = true;
812    return aret_success;
813 }
814
815 bool thread_db_process::plat_convertToBreakpointAddress(Address &, int_thread *) {
816     // Default behavior is no translation
817     return true;
818 }
819
820 void thread_db_process::freeThreadDBAgent() {
821     // This code cannot be in the destructor because it makes use of
822     // the proc_service interface and this makes calls to functions
823     // that are pure virtual in this class.
824     //
825     // A possible, better solution would be to make the functions static
826     // but we lose all the convenience of pure virtual functions
827     //
828     // At any rate, this function should be called from a derived class' 
829     // destructor for the time being.
830
831     if( thread_db_initialized && threadAgent ) {
832         td_err_e errVal = p_td_ta_delete(threadAgent);
833         if( TD_OK != errVal ) {
834             perr_printf("Failed to delete thread agent: %s(%d)\n",
835                     tdErr2Str(errVal), errVal);
836         }
837         assert( TD_OK == errVal && "Failed to delete thread agent" );
838         threadAgent = NULL;
839     }
840 }
841
842 const char *thread_db_process::getThreadLibName(const char *)
843 {
844    return "";
845 }
846
847 bool thread_db_process::decodeTdbLWPExit(EventLWPDestroy::ptr lwp_ev)
848 {
849    thread_db_thread *db_thread = dynamic_cast<thread_db_thread *>(lwp_ev->getThread()->llthrd());
850    assert(db_thread);
851    
852    if (db_thread->destroyed || !db_thread->thread_initialized)
853       return false;
854
855    pthrd_printf("Decoded LWP exit without thread exit on %d/%d.  Faking thread exit event\n",
856                 db_thread->llproc()->getPid(), db_thread->getLWP());
857    
858    EventUserThreadDestroy::ptr new_ev = EventUserThreadDestroy::ptr(new EventUserThreadDestroy(EventType::Post));
859    new_ev->setProcess(db_thread->llproc()->proc());
860    new_ev->setThread(db_thread->thread());
861    lwp_ev->addSubservientEvent(new_ev);
862    return true;
863 }
864
865 async_ret_t thread_db_process::decodeTdbBreakpoint(EventBreakpoint::ptr bp)
866
867     // Decoding thread_db events needs to be a two-step process:
868     // 1) Create events depending on the breakpoint address
869     //    Don't get events from thread_db as this can write to memory
870     //    and threads could currently be running -- introduces some race
871     //    conditions where the running threads could be modifying data
872     //    structures thread_db is accessing
873     //    Just create placeholder events that can later be filled in with
874     //    more information
875     // 2) Get events from thread_db in the handler for the event, at this
876     //    point all threads are stopped and it is safe to make changes to
877     //    memory because the parent event is a breakpoint and requires
878     //    that all threads are stopped
879     Dyninst::Address addr = bp->getAddress();
880     
881     // Determine what type of event occurs at the specified address
882     map<Dyninst::Address, pair<int_breakpoint *, EventType> >::iterator addrIter;
883     addrIter = addr2Event.find(addr);
884     if (addrIter == addr2Event.end()) 
885        return aret_error;
886
887     vector<Event::ptr> threadEvents;
888
889     EventType::Code ecode = addrIter->second.second.code();
890     pthrd_printf("Address 0x%lx corresponds to a thread %s breakpoint.\n",
891                  addr, ecode == EventType::ThreadCreate ? "create" : "destroy");
892     switch(ecode) {
893        case EventType::ThreadCreate:
894        case EventType::ThreadDestroy:
895           threadEvents.push_back(EventThreadDB::ptr(new EventThreadDB()));
896           break;
897        default:
898           pthrd_printf("Failed to decode any thread events due to the breakpoint\n");
899           return aret_error;
900     }
901
902     for (vector<Event::ptr>::iterator i = threadEvents.begin(); i != threadEvents.end(); i++) {
903        Event::ptr ev = *i;
904        if (!ev->getThread()) 
905           ev->setThread(bp->getThread());
906        if (!ev->getProcess()) 
907           ev->setProcess(proc());
908        bp->addSubservientEvent(ev);
909     }
910     bp->setSuppressCB(true);
911     return aret_success;
912 }
913
914 td_thragent_t *thread_db_process::getThreadDBAgent() {
915     return threadAgent;
916 }
917
918 static string stripLibraryName(const char *libname)
919 {
920    const char *filename_c = strrchr(libname, '/');
921    if (!filename_c)
922       filename_c = strrchr(libname, '\\');
923    if (!filename_c) 
924       filename_c = libname;
925    else 
926       filename_c++;
927    
928    const char *lesser_ext = NULL;
929    const char *dot_ext = strchr(filename_c, '.');
930    if (dot_ext)
931       lesser_ext = dot_ext;
932    const char *dash_ext = strchr(filename_c, '-');
933    if (dash_ext && (!lesser_ext || dash_ext < lesser_ext))
934       lesser_ext = dash_ext;
935
936    if (!lesser_ext) {
937       return std::string(filename_c);
938    }
939    return std::string(filename_c, lesser_ext - filename_c);
940 }
941
942 ps_err_e thread_db_process::getSymbolAddr(const char *objName, const char *symName,
943         psaddr_t *symbolAddr)
944 {
945     SymReader *objSymReader = NULL;
946     int_library *lib = NULL;
947     
948     if (plat_isStaticBinary()) {
949        // For static executables, we need to search the executable instead of the
950        // thread library. 
951        assert(memory()->libs.size() == 1);
952        lib = *memory()->libs.begin();
953     }
954     else
955     {
956        // FreeBSD implementation doesn't set objName
957        const char *name_c = objName ? objName : getThreadLibName(symName);
958        std::string name = stripLibraryName(name_c);
959        
960        for (set<int_library *>::iterator i = memory()->libs.begin(); i != memory()->libs.end(); i++) {
961           int_library *l = *i;
962           if (strstr(l->getName().c_str(), name.c_str())) {
963              lib = l;
964              break;
965           }
966        }
967     }
968
969     if( NULL == lib ) {
970        pthrd_printf("Didn't yet find loaded thread library\n");
971        return PS_ERR;
972     }
973
974     objSymReader = plat_defaultSymReader()->openSymbolReader(lib->getName());
975     if( NULL == objSymReader ) {
976         perr_printf("Failed to open symbol reader for %s\n",
977                     lib->getName().c_str());
978         setLastError(err_internal, "Failed to open executable for symbol reading");
979         return PS_ERR;
980     }
981
982     Symbol_t lookupSym = objSymReader->getSymbolByName(string(symName));
983
984     if( !objSymReader->isValidSymbol(lookupSym) ) {
985        pthrd_printf("thread_db getSymbolAddr(%s, %s) = none\n", objName ? objName : "NULL", 
986                     symName ? symName : "NULL");
987        return PS_NOSYM;
988     }
989
990     *symbolAddr = (psaddr_t) (lib->getAddr() + 
991                               objSymReader->getSymbolOffset(lookupSym));
992
993     pthrd_printf("thread_db getSymbolAddr(%s, %s) = %p\n", objName ? objName : "NULL", 
994                  symName ? symName : "NULL", *symbolAddr);
995     return PS_OK;
996 }
997
998
999 async_ret_t thread_db_process::post_create(std::set<response::ptr> &async_responses)
1000 {
1001    async_ret_t result;
1002    if (!completed_post) {
1003       result = int_process::post_create(async_responses);
1004       if (result != aret_success)
1005          return result;
1006       completed_post = true;
1007    }
1008
1009    getMemCache()->setSyncHandling(true);
1010    for (;;) {
1011       result = initThreadDB();
1012       if (result != aret_async)
1013          break;
1014       getMemCache()->getPendingAsyncs(async_responses);
1015       return aret_async;
1016    }
1017    getMemCache()->setSyncHandling(false);
1018
1019    return aret_success; //Swallow these errors, thread_db failure does not bring down rest of startup
1020 }
1021
1022 async_ret_t thread_db_process::post_attach(bool wasDetached, set<response::ptr> &aresps) {
1023    async_ret_t result;
1024    if (!completed_post) {
1025       result = int_process::post_attach(wasDetached, aresps);
1026       if (result != aret_success)
1027          return result;
1028       completed_post = true;
1029    }
1030    
1031    getMemCache()->setSyncHandling(true);
1032    for (;;) {
1033       result = initThreadDB();
1034       if (result != aret_async)
1035          break;
1036       getMemCache()->getPendingAsyncs(aresps);
1037       return aret_async;
1038    }
1039    getMemCache()->setSyncHandling(false);
1040
1041    return aret_success;
1042 }
1043
1044 #if 0
1045 #warning TODO fix detach part in post attach rewrite
1046 bool thread_db_process::post_attach(bool wasDetached) {
1047     if( !int_process::post_attach(wasDetached) ) return false;
1048
1049     if( !wasDetached ) {
1050         return initThreadDB();
1051     }else{
1052         // Need to initialize all new threads
1053         bool success = true;
1054         td_err_e errVal;
1055         for (int_threadPool::iterator i = threadPool()->begin(); i != threadPool()->end(); i++) {
1056            thread_db_thread *tdb_thread = static_cast<thread_db_thread *>(*i);
1057            if( tdb_thread->thread_initialized ) continue;
1058
1059            tdb_thread->threadHandle = new td_thrhandle_t;
1060
1061            errVal = td_ta_map_lwp2thr(getThreadDBAgent(), tdb_thread->getLWP(), tdb_thread->threadHandle);
1062            if (errVal != TD_OK) {
1063               perr_printf("Failed to map LWP %d to thread_db thread: %s(%d)\n",
1064                           tdb_thread->getLWP(), tdErr2Str(errVal), errVal);
1065               setLastError(err_internal, "Failed to get thread_db thread handle");
1066               delete tdb_thread->threadHandle;
1067               tdb_thread->threadHandle = NULL;
1068               success = false;
1069               continue;
1070            }
1071            tdb_thread->threadHandle_alloced = true;
1072
1073            if( !handleThreadAttach(tdb_thread->threadHandle) ) {
1074                perr_printf("Error handling thread_db attach\n");
1075                success = false;
1076            }
1077         }
1078
1079         return success;
1080     }
1081 }
1082 #endif
1083
1084 bool thread_db_process::isSupportedThreadLib(string libName) {
1085    return (libName.find("libpthread") != string::npos);
1086 }
1087
1088 void thread_db_process::addThreadDBHandlers(HandlerPool *hpool) {
1089    static bool initialized = false;
1090    static ThreadDBLibHandler *libHandler = NULL;
1091    static ThreadDBCreateHandler *createHandler = NULL;
1092    static ThreadDBDestroyHandler *destroyHandler = NULL;
1093    static ThreadDBDispatchHandler *dispatchHandler = NULL;
1094    if( !initialized ) {
1095       libHandler = new ThreadDBLibHandler();
1096       createHandler = new ThreadDBCreateHandler();
1097       destroyHandler = new ThreadDBDestroyHandler();
1098       dispatchHandler = new ThreadDBDispatchHandler();
1099       initialized = true;
1100    }
1101    hpool->addHandler(libHandler);
1102    hpool->addHandler(createHandler);
1103    hpool->addHandler(destroyHandler);
1104    hpool->addHandler(dispatchHandler);
1105 }
1106
1107 bool thread_db_process::plat_getLWPInfo(lwpid_t, void *) 
1108 {
1109    perr_printf("Attempt to use unsupported plat_getLWPInfo\n");
1110    return false;
1111 }
1112
1113 bool thread_db_process::plat_supportThreadEvents()
1114 {
1115    if (!loadedThreadDBLibrary()) {
1116       return false;
1117    }
1118    return true;
1119 }
1120
1121 bool thread_db_thread::plat_convertToSystemRegs(const int_registerPool &,
1122                                                 unsigned char *)
1123 {
1124     return true;
1125 }
1126
1127 int_thread *thread_db_process::triggerThread() const
1128 {
1129    return trigger_thread;
1130 }
1131
1132 async_ret_t thread_db_process::ll_fetchThreadInfo(td_thrhandle_t *th, td_thrinfo_t *info)
1133 {
1134    td_err_e result = thread_db_process::p_td_thr_get_info(th, info);
1135    if (result != TD_OK) {
1136       if (getMemCache()->hasPendingAsync()) {
1137          pthrd_printf("Async return from td_thr_get_info in ll_fetchThreadInfo\n");
1138          return aret_async;
1139       }
1140       perr_printf("Error calling td_thr_get_info: %s (%d)\n", tdErr2Str(result), (int) result);
1141       return aret_error;
1142    }
1143    return aret_success;
1144 }
1145
1146 ThreadDBDispatchHandler::ThreadDBDispatchHandler() :
1147    Handler("thread_db Dispatch Handler")
1148 {
1149 }
1150
1151 ThreadDBDispatchHandler::~ThreadDBDispatchHandler()
1152 {
1153 }
1154
1155 int ThreadDBDispatchHandler::getPriority() const
1156 {
1157    return Handler::PostPlatformPriority;
1158 }
1159
1160 Handler::handler_ret_t ThreadDBDispatchHandler::handleEvent(Event::ptr ev)
1161 {
1162    /**
1163     * All we know is that we got a thread_db breakpoint, but we don't
1164     * know whether that was a thread create/destroy, or any information
1165     * about those events.  We'll collect that info here, then add
1166     * UserThreadCreate or UserThreadDestroy events as 'late' events 
1167     * (means they were generated at handle time) to this event.
1168     **/
1169    pthrd_printf("At top of ThreadDB Dispatch handler\n");
1170    EventThreadDB::ptr etdb = ev->getEventThreadDB();
1171    assert(etdb);
1172    int_eventThreadDB *int_ev = etdb->getInternal();
1173    assert(int_ev);
1174
1175    thread_db_process *proc = dynamic_cast<thread_db_process *>(etdb->getProcess()->llproc());
1176    assert(proc);
1177
1178    if (proc->dispatch_event && proc->dispatch_event != etdb) {
1179       //We don't need to handle a new dispatch event if another is in
1180       //progress.  We'll drop the second.
1181       pthrd_printf("Dropping dispatch event, another is in progress\n");
1182       return ret_success;
1183    }
1184    proc->dispatch_event = etdb;
1185
1186    if (!int_ev->completed_new_evs) {
1187       async_ret_t result = proc->getEventForThread(int_ev->new_evs);
1188       if (result == aret_async) {
1189          pthrd_printf("getEventForThread returned async\n");
1190          return ret_async;
1191       }
1192       int_ev->completed_new_evs = true;
1193       if (result == aret_error) {
1194          pthrd_printf("getEventForThread returned error\n");
1195          proc->dispatch_event = EventThreadDB::ptr();
1196          return ret_error;
1197       }
1198    }
1199
1200    thread_db_thread *main_thread = dynamic_cast<thread_db_thread *>(proc->threadPool()->initialThread());
1201    if (main_thread->tinfo_initialized)
1202       proc->initialThreadEventCreated = true;
1203
1204    if (!proc->initialThreadEventCreated) {
1205       pthrd_printf("Creating thread event for main thread\n");
1206
1207       if (!main_thread->threadHandle) {
1208          main_thread->threadHandle = new td_thrhandle_t;
1209          main_thread->threadHandle_alloced = true;
1210       }
1211
1212       int td_result = thread_db_process::p_td_ta_map_lwp2thr(proc->getThreadDBAgent(), main_thread->getLWP(), main_thread->threadHandle);
1213       if (td_result == TD_ERR && proc->getMemCache()->hasPendingAsync()) {
1214          pthrd_printf("async return from td_ta_map_lwp2thr while creating event for main thread\n");
1215          std::set<response::ptr> resps;
1216          proc->getMemCache()->getPendingAsyncs(resps);
1217          proc->handlerPool()->notifyOfPendingAsyncs(resps, ev);
1218          return Handler::ret_async;
1219       }
1220       else if (td_result == TD_ERR) {
1221          perr_printf("Error return from td_ta_map_lwp2thr while creating event for main thread\n");
1222          proc->dispatch_event = EventThreadDB::ptr();
1223          return ret_error;
1224       }
1225
1226       td_thrinfo_t tinfo;
1227       bzero(&tinfo, sizeof(td_thrinfo_t));
1228       async_ret_t result = proc->ll_fetchThreadInfo(main_thread->threadHandle, &tinfo);
1229       if (result == aret_async) {
1230          pthrd_printf("Async return during ll_fetchThreadInfo for main thread\n");
1231          std::set<response::ptr> resps;
1232          proc->getMemCache()->getPendingAsyncs(resps);
1233          proc->handlerPool()->notifyOfPendingAsyncs(resps, ev);
1234          return Handler::ret_async;         
1235       }
1236       if (result == aret_error) {
1237          pthrd_printf("Error return during ll_fetchThreadInfo for main thread\n");
1238          proc->dispatch_event = EventThreadDB::ptr();
1239          return Handler::ret_error;
1240       }
1241       if (tinfo.ti_tid) {
1242          new_thread_data_t *thrdata = (new_thread_data_t *) malloc(sizeof(new_thread_data_t));
1243          thrdata->thr_handle = main_thread->threadHandle;
1244          thrdata->thr_info = tinfo;
1245          thrdata->threadHandle_alloced = main_thread->threadHandle_alloced;
1246          
1247          EventNewUserThread::ptr new_ev = EventNewUserThread::ptr(new EventNewUserThread());
1248          new_ev->setProcess(proc->proc());
1249          new_ev->setThread(main_thread->thread());
1250          new_ev->setSyncType(Event::sync_process);
1251          new_ev->getInternalEvent()->thr = main_thread;
1252          new_ev->getInternalEvent()->lwp = main_thread->getLWP();
1253          new_ev->getInternalEvent()->raw_data = (void *) thrdata;
1254          proc->initialThreadEventCreated = true;
1255          int_ev->new_evs.insert(new_ev);
1256          pthrd_printf("Success creating event for main thread\n");
1257       }
1258       else {
1259          pthrd_printf("TID info for main thread not ready yet\n");
1260       }
1261    }
1262    pthrd_printf("Got %u events, adding as late events\n", (unsigned int) int_ev->new_evs.size());
1263    for (set<Event::ptr>::iterator i = int_ev->new_evs.begin(); i != int_ev->new_evs.end(); i++) {
1264       proc->handlerPool()->addLateEvent(*i);
1265    }
1266    proc->dispatch_event = EventThreadDB::ptr();
1267    return ret_success;
1268 }
1269
1270 void ThreadDBDispatchHandler::getEventTypesHandled(std::vector<EventType> &etypes)
1271 {
1272    etypes.push_back(EventType(EventType::None, EventType::ThreadDB));
1273 }
1274
1275 ThreadDBLibHandler::ThreadDBLibHandler() :
1276     Handler("thread_db Library Handler")
1277 {
1278 }
1279
1280 ThreadDBLibHandler::~ThreadDBLibHandler() 
1281 {
1282 }
1283
1284 Handler::handler_ret_t ThreadDBLibHandler::handleEvent(Event::ptr ev) {
1285    if (!thread_db_process::loadedThreadDBLibrary()) {
1286       pthrd_printf("Failed to load thread_db.  Not running handlers\n");
1287       return Handler::ret_success;
1288    }
1289
1290    EventLibrary::const_ptr libEv = ev->getEventLibrary();
1291    thread_db_process *proc = dynamic_cast<thread_db_process *>(ev->getProcess()->llproc());
1292    const set<Library::ptr> &addLibs = libEv->libsAdded();
1293
1294    set<Library::ptr>::iterator libIter;
1295    for( libIter = addLibs.begin(); libIter != addLibs.end(); ++libIter ) {
1296       if( ! proc->isSupportedThreadLib((*libIter)->getName()) )
1297          continue;
1298       
1299       pthrd_printf("Enabling thread_db support for pid %d\n",
1300                    proc->getPid());
1301       async_ret_t ret = proc->initThreadDB();
1302  
1303       if (ret == aret_error) {
1304          pthrd_printf("Failed to initialize thread_db for pid %d\n",
1305                       proc->getPid());
1306          return Handler::ret_error;
1307       }
1308       else if (ret == aret_success) {
1309          return Handler::ret_success;
1310       }
1311       else if (ret == aret_async) {
1312          std::set<response::ptr> resps;
1313          proc->getMemCache()->getPendingAsyncs(resps);
1314          proc->handlerPool()->notifyOfPendingAsyncs(resps, ev);
1315          return Handler::ret_async;
1316       }
1317    }
1318    
1319    return Handler::ret_success;
1320 }
1321
1322 int ThreadDBLibHandler::getPriority() const {
1323     return PostPlatformPriority;
1324 }
1325
1326 void ThreadDBLibHandler::getEventTypesHandled(vector<EventType> &etypes) {
1327     etypes.push_back(EventType(EventType::None, EventType::Library));
1328 }
1329
1330 ThreadDBCreateHandler::ThreadDBCreateHandler() :
1331     Handler("thread_db New Thread Handler")
1332 {
1333 }
1334
1335 ThreadDBCreateHandler::~ThreadDBCreateHandler() 
1336 {
1337 }
1338
1339 int ThreadDBCreateHandler::getPriority() const
1340 {
1341    //After dispatch handler, which runs at PostPlatformPriority
1342    return Handler::PostPlatformPriority + 1;
1343 }
1344
1345 Handler::handler_ret_t ThreadDBCreateHandler::handleEvent(Event::ptr ev) {
1346    if (!thread_db_process::loadedThreadDBLibrary()) {
1347       pthrd_printf("Failed to load thread_db.  Not running handlers");
1348       return Handler::ret_success;
1349    }
1350
1351    EventNewUserThread::ptr threadEv = ev->getEventNewUserThread();
1352    thread_db_process *tdb_proc = dynamic_cast<thread_db_process *>(threadEv->getProcess()->llproc());
1353    thread_db_thread *tdb_thread = dynamic_cast<thread_db_thread *>(threadEv->getNewThread()->llthrd());
1354
1355    pthrd_printf("ThreadDBCreateHandler::handleEvent for %d/%d\n", tdb_proc->getPid(), tdb_thread->getLWP());
1356    if (threadEv->getInternalEvent()->needs_update) {
1357       pthrd_printf("Updating user thread data for %d/%d in thread_db create handler\n",
1358                    tdb_proc->getPid(), tdb_thread->getLWP());
1359       assert(tdb_proc);
1360       new_thread_data_t *thrdata = (new_thread_data_t *) threadEv->getInternalEvent()->raw_data;
1361       
1362       async_ret_t result = tdb_proc->initThreadWithHandle(thrdata->thr_handle, &thrdata->thr_info, NULL_LWP);
1363       if (result == aret_error) {
1364          pthrd_printf("ThreadDBCreateHandler returning error\n");
1365          return Handler::ret_error;
1366       }
1367       if (result == aret_async) {
1368          pthrd_printf("ThreadDBCreateHandler returning async\n");
1369          return Handler::ret_async;
1370       }
1371       if (thrdata->threadHandle_alloced) tdb_thread->threadHandle_alloced = true;
1372    }
1373    
1374    return Handler::ret_success;
1375 }
1376
1377 void ThreadDBCreateHandler::getEventTypesHandled(vector<EventType> &etypes) {
1378    etypes.push_back(EventType(EventType::Any, EventType::UserThreadCreate));
1379 }
1380
1381 ThreadDBDestroyHandler::ThreadDBDestroyHandler() :
1382    Handler("thread_db Destroy Handler")
1383 {
1384 }
1385
1386 ThreadDBDestroyHandler::~ThreadDBDestroyHandler()
1387 {
1388 }
1389
1390 int ThreadDBDestroyHandler::getPriority() const
1391 {
1392    //After dispatch handler, which runs at PostPlatformPriority
1393    return Handler::PostPlatformPriority + 1;
1394 }
1395
1396 Handler::handler_ret_t ThreadDBDestroyHandler::handleEvent(Event::ptr ev) {
1397    if (!thread_db_process::loadedThreadDBLibrary()) {
1398       pthrd_printf("Failed to load thread_db.  Not running handlers\n");
1399       return Handler::ret_success;
1400    }
1401    thread_db_process *proc = dynamic_cast<thread_db_process *>(ev->getProcess()->llproc());
1402    thread_db_thread *thrd = dynamic_cast<thread_db_thread *>(ev->getThread()->llthrd());
1403    pthrd_printf("Running ThreadDBDestroyHandler on %d/%d\n", proc->getPid(), thrd->getLWP());
1404    thrd->markDestroyed();
1405
1406    return Handler::ret_success;
1407 }
1408
1409 void ThreadDBDestroyHandler::getEventTypesHandled(vector<EventType> &etypes) {
1410     etypes.push_back(EventType(EventType::Any, EventType::UserThreadDestroy));
1411 }
1412
1413 thread_db_thread::thread_db_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l) :
1414    int_thread(p, t, l),
1415    threadHandle(NULL),
1416    destroyed(false),
1417    tinfo_initialized(false),
1418    thread_initialized(false),
1419    threadHandle_alloced(false),
1420    enabled_event_reporting(false)
1421 {
1422    memset(&tinfo, 0, sizeof(tinfo));
1423 }
1424
1425 thread_db_thread::~thread_db_thread() 
1426 {
1427    if (threadHandle_alloced)
1428       delete threadHandle;
1429 }
1430
1431 bool thread_db_thread::initThreadHandle() {
1432     if( NULL != threadHandle ) return true;
1433
1434     thread_db_process *lproc = dynamic_cast<thread_db_process *>(llproc());
1435     if( NULL == lproc->getThreadDBAgent() ) return false;
1436
1437     threadHandle = new td_thrhandle_t;
1438
1439     td_err_e errVal = thread_db_process::p_td_ta_map_lwp2thr(lproc->getThreadDBAgent(),
1440                                           lwp, threadHandle);
1441     if( TD_OK != errVal ) {
1442         perr_printf("Failed to map LWP %d to thread_db thread: %s(%d)\n",
1443                 lwp, tdErr2Str(errVal), errVal);
1444         setLastError(err_internal, "Failed to get thread_db thread handle");
1445         delete threadHandle;
1446         threadHandle = NULL;
1447         return false;
1448     }
1449     threadHandle_alloced = true;
1450
1451     return true;
1452 }
1453
1454 async_ret_t thread_db_process::getEventForThread(set<Event::ptr> &new_ev_set) {
1455    // These specific calls into thread_db can modify the memory of the process
1456    // and can introduce some race conditions if the platform allows memory reads
1457    // while some threads are running
1458    assert( threadPool()->allHandlerStopped() );
1459   
1460    // We need to save thread_db generated events because we need to use the
1461    // process-level event retrieval call to get thread creation events (at
1462    // least on some platforms).
1463
1464    bool local_async = false;
1465    td_event_msg_t evMsg;
1466    td_err_e msgErr = TD_OK;
1467    for (;;) {
1468       getMemCache()->markToken(token_getmsg);
1469       msgErr = p_td_ta_event_getmsg(threadAgent, &evMsg);
1470       if (msgErr != TD_OK) {
1471          if (getMemCache()->hasPendingAsync()) {
1472             pthrd_printf("Async return in getEventForThread from td_ta_event_getmsg\n");
1473             return aret_async;
1474          }
1475          else if (msgErr == TD_DBERR) {
1476             pthrd_printf("No more messages ready in thread_db\n");
1477             return aret_success;
1478          }
1479          else
1480             break;
1481       }
1482       Event::ptr newEvent = decodeThreadEvent(&evMsg, local_async);
1483       if (local_async) {
1484          pthrd_printf("Async return from decodeThreadEvent\n");
1485          return aret_async;
1486       }
1487       if (newEvent)
1488          new_ev_set.insert(newEvent);
1489       getMemCache()->condense();
1490    }
1491   
1492    if( msgErr != TD_NOMSG ) {
1493       perr_printf("Failed to retrieve thread event: %s(%d)\n",
1494                   tdErr2Str(msgErr), msgErr);
1495       return aret_error;
1496    }
1497   
1498    return aret_success;
1499 }
1500
1501 async_ret_t thread_db_thread::setEventReporting(bool on) {
1502     if( !initThreadHandle() ) return aret_error;
1503     if (enabled_event_reporting == on) return aret_success;
1504
1505     pthrd_printf("Enabled thread_db events for LWP %d\n", lwp);
1506     td_err_e errVal = thread_db_process::p_td_thr_event_enable(threadHandle, (on ? 1 : 0 ));
1507     if (errVal != TD_OK && llproc()->getMemCache()->hasPendingAsync()) {
1508        pthrd_printf("td_thr_event_enable returned async in setEventReporting\n");
1509        return aret_async;
1510     }
1511     enabled_event_reporting = on;
1512     if (errVal != TD_OK) {
1513        perr_printf("Failed to enable events for LWP %d: %s(%d)\n",
1514                    lwp, tdErr2Str(errVal), errVal);
1515        setLastError(err_internal, "Failed to enable thread_db events");
1516        return aret_error;
1517     }
1518
1519     return aret_success;
1520 }
1521
1522 bool thread_db_thread::fetchThreadInfo() {
1523    if (!thread_db_process::loadedThreadDBLibrary()) {
1524       perr_printf("Failed to load thread_db.  Not fetching thread data.");
1525       setLastError(err_unsupported, "thread_db.so not loaded.  User-level thread data unavailable.");
1526       return false;
1527    }
1528    if (!thread_initialized) {
1529       perr_printf("Attempt to read user thread info of %d/%d before user thread create\n",
1530                   llproc()->getPid(), getLWP());
1531       setLastError(err_nouserthrd, "Attempted to read user thread info, but user thread has not been created.");
1532       return false;
1533    }
1534    if (tinfo_initialized) {
1535       return true;
1536    }
1537    if( !initThreadHandle() ) return false;
1538
1539    pthrd_printf("Calling td_thr_get_info on %d/%d\n", llproc()->getPid(), getLWP());
1540    thread_db_process *tdb_proc = dynamic_cast<thread_db_process *>(llproc());
1541    async_ret_t result = tdb_proc->ll_fetchThreadInfo(threadHandle, &tinfo);
1542    if (result == aret_error) {
1543       pthrd_printf("Returning error in fetchThreadInfo due to ll_fetchThreadInfo\n");
1544       return false;
1545    }
1546    while (result == aret_async) {
1547       std::set<response::ptr> resps;
1548       llproc()->getMemCache()->getPendingAsyncs(resps);
1549       llproc()->waitForAsyncEvent(resps);
1550       result = tdb_proc->ll_fetchThreadInfo(threadHandle, &tinfo);
1551       if (result == aret_error) {
1552          pthrd_printf("Returning error in fetchThreadInfo due to ll_fetchThreadInfo\n");
1553          return false;
1554       }
1555    }
1556
1557    if( tinfo.ti_tid ) tinfo_initialized = true;
1558    return true;
1559 }
1560
1561 void thread_db_thread::markDestroyed() {
1562     destroyed = true;
1563 }
1564
1565 bool thread_db_thread::isDestroyed() {
1566     return destroyed;
1567 }
1568
1569 bool thread_db_thread::thrdb_getThreadArea(int, Dyninst::Address &)
1570 {
1571    assert(0); //Unsupported.  Currently only known to be needed on linux/x86_64
1572    return false;
1573 }
1574
1575 bool thread_db_thread::haveUserThreadInfo()
1576 {
1577    return thread_initialized;
1578 }
1579
1580 bool thread_db_thread::getTID(Dyninst::THR_ID &tid)
1581 {
1582    if (!fetchThreadInfo()) {
1583       return false;
1584    }
1585 #if defined(os_freebsd)
1586    tid = (Dyninst::THR_ID) tinfo.ti_thread;
1587 #else
1588    tid = (Dyninst::THR_ID) tinfo.ti_tid;
1589 #endif
1590    return true;
1591 }
1592
1593 bool thread_db_thread::getStartFuncAddress(Dyninst::Address &addr)
1594 {
1595    if (!fetchThreadInfo()) {
1596       return false;
1597    }
1598    addr = (Dyninst::Address) tinfo.ti_startfunc;
1599    return true;
1600 }
1601
1602 bool thread_db_thread::getStackBase(Dyninst::Address &addr)
1603 {
1604    if (!fetchThreadInfo()) {
1605       return false;
1606    }
1607    addr = (Dyninst::Address) tinfo.ti_stkbase;
1608    return true;
1609 }
1610
1611 bool thread_db_thread::getStackSize(unsigned long &size)
1612 {
1613    if (!fetchThreadInfo()) {
1614       return false;
1615    }
1616    size = (unsigned long) tinfo.ti_stksize;
1617    return true;
1618 }
1619
1620 bool thread_db_thread::getTLSPtr(Dyninst::Address &addr)
1621 {
1622    if (!fetchThreadInfo()) {
1623       return false;
1624    }
1625    addr = (Dyninst::Address) tinfo.ti_tls;
1626    return true;
1627 }
1628
1629 #else
1630
1631 //Empty place holder functions in-case we're built on a machine wihtout libthread_db.so
1632
1633 thread_db_process::thread_db_process(Dyninst::PID p, std::string e, std::vector<std::string> a, std::vector<std::string> envp, std::map<int, int> f) : 
1634    int_process(p, e, a, envp, f)
1635 {
1636 }
1637
1638 thread_db_process::thread_db_process(Dyninst::PID pid_, int_process *p) :
1639    int_process(pid_, p)
1640 {
1641 }
1642
1643 thread_db_process::~thread_db_process()
1644 {
1645 }
1646
1647 bool thread_db_process::decodeTdbLWPExit(EventLWPDestroy::ptr)
1648 {
1649    return false;
1650 }
1651
1652 bool thread_db_process::decodeThreadBP(EventBreakpoint::ptr)
1653 {
1654    return false;
1655 }
1656
1657 async_ret_t thread_db_process::decodeTdbBreakpoint(EventBreakpoint::ptr)
1658 {
1659    return aret_error;
1660 }
1661
1662 void thread_db_process::addThreadDBHandlers(HandlerPool *)
1663 {
1664 }
1665
1666 thread_db_thread::thread_db_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l) : 
1667    int_thread(p, t, l)
1668 {
1669 }
1670
1671 thread_db_thread::~thread_db_thread()
1672 {
1673 }
1674
1675 bool thread_db_thread::thrdb_getThreadArea(int, Dyninst::Address &)
1676 {
1677    assert(0); //Should not be called if there's no thread_db
1678    return false;
1679 }
1680
1681 bool thread_db_thread::haveUserThreadInfo()
1682 {
1683    return false;
1684 }
1685
1686 bool thread_db_thread::getTID(Dyninst::THR_ID &)
1687 {
1688    perr_printf("Error. thread_db not installed on this platform.\n");
1689    setLastError(err_unsupported, "Cannot perform thread operations without thread_db\n");
1690    return false;
1691 }
1692
1693 bool thread_db_thread::getStartFuncAddress(Dyninst::Address &)
1694 {
1695    perr_printf("Error. thread_db not installed on this platform.\n");
1696    setLastError(err_unsupported, "Cannot perform thread operations without thread_db\n");
1697    return false;
1698 }
1699
1700 bool thread_db_thread::getStackBase(Dyninst::Address &)
1701 {
1702    perr_printf("Error. thread_db not installed on this platform.\n");
1703    setLastError(err_unsupported, "Cannot perform thread operations without thread_db\n");
1704    return false;
1705 }
1706
1707 bool thread_db_thread::getStackSize(unsigned long &)
1708 {
1709    perr_printf("Error. thread_db not installed on this platform.\n");
1710    setLastError(err_unsupported, "Cannot perform thread operations without thread_db\n");
1711    return false;
1712 }
1713
1714 bool thread_db_thread::getTLSPtr(Dyninst::Address &)
1715 {
1716    perr_printf("Error. thread_db not installed on this platform.\n");
1717    setLastError(err_unsupported, "Cannot perform thread operations without thread_db\n");
1718    return false;
1719 }
1720
1721 #endif