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