static int thread_db_enable_reporting () { td_thr_events_t events; td_notify_t notify; td_err_e err; /* Set the process wide mask saying which events we're interested in. */ td_event_emptyset (&events); td_event_addset (&events, TD_CREATE); #if 0 /* This is reported to be broken in glibc 2.1.3. A different approach will be necessary to support that. */ td_event_addset (&events, TD_DEATH); #endif err = td_ta_set_event (thread_agent, &events); if (err != TD_OK) { warning ("Unable to set global thread event mask: %s", thread_db_err_str (err)); return 0; } /* Get address for thread creation breakpoint. */ err = td_ta_event_addr (thread_agent, TD_CREATE, ¬ify); if (err != TD_OK) { warning ("Unable to get location for thread creation breakpoint: %s", thread_db_err_str (err)); return 0; } set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, thread_db_create_event); #if 0 /* Don't concern ourselves with reported thread deaths, only with actual thread deaths (via wait). */ /* Get address for thread death breakpoint. */ err = td_ta_event_addr (thread_agent, TD_DEATH, ¬ify); if (err != TD_OK) { warning ("Unable to get location for thread death breakpoint: %s", thread_db_err_str (err)); return; } set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, thread_db_death_event); #endif return 1; }
//-------------------------------------------------------------------------- void linux_debmod_t::tdb_enable_event(td_event_e event, internal_bpt *bp) { td_notify_t notify; td_err_e err = td_ta_event_addr(ta, event, ¬ify); DIE_IF_FAILED("td_ta_event_addr", err); bool ok = add_internal_bp(*bp, size_t(notify.u.bptaddr)); debdeb("%a: added BP for thread event %s\n", bp->bpt_addr, event == TD_CREATE ? "TD_CREATE" : "TD_DEATH"); QASSERT(ok); }