/* libthread_db assisted debugging support, generic parts.
- Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GDB.
static struct target_ops *target_beneath;
/* Pointer to the next function on the objfile event chain. */
-static void (*target_new_objfile_chain) (struct objfile *objfile);
+static void (*target_new_objfile_chain) (struct objfile * objfile);
/* Non-zero if we're using this module's target vector. */
static int using_thread_db;
static td_err_e (*td_init_p) (void);
-static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
+static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
+ td_thragent_t **ta);
static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
td_thrhandle_t *__th);
-static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
- td_thrhandle_t *th);
+static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
+ lwpid_t lwpid, td_thrhandle_t *th);
static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
- td_thr_iter_f *callback,
- void *cbdata_p, td_thr_state_e state,
- int ti_pri, sigset_t *ti_sigmask_p,
+ td_thr_iter_f *callback, void *cbdata_p,
+ td_thr_state_e state, int ti_pri,
+ sigset_t *ti_sigmask_p,
unsigned int ti_user_flags);
static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
td_event_e event, td_notify_t *ptr);
const gdb_prfpregset_t *fpregs);
static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
prgregset_t gregs);
-static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
+static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
+ int event);
static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
- void *map_address,
- size_t offset,
- void **address);
+ void *map_address,
+ size_t offset, void **address);
/* Location of the thread creation event breakpoint. The code at this
location in the child process will be called by the pthread library
struct private_thread_info
{
/* Cached thread state. */
- unsigned int th_valid : 1;
- unsigned int ti_valid : 1;
+ unsigned int th_valid:1;
+ unsigned int ti_valid:1;
td_thrhandle_t th;
td_thrinfo_t ti;
err = td_thr_get_info_p (thp, &ti);
if (err != TD_OK)
- error ("thread_get_info_callback: cannot get thread info: %s",
+ error ("thread_get_info_callback: cannot get thread info: %s",
thread_db_err_str (err));
/* Fill the cache. */
{
if (fatal)
error ("Cannot find thread %ld: %s",
- (long) GET_THREAD (thread_info->ptid), thread_db_err_str (err));
+ (long) GET_THREAD (thread_info->ptid),
+ thread_db_err_str (err));
}
else
thread_info->private->th_valid = 1;
if (thread_info->private->ti_valid)
return &thread_info->private->ti;
- if (! thread_info->private->th_valid)
+ if (!thread_info->private->th_valid)
thread_db_map_id2thr (thread_info, 1);
- err = td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
+ err =
+ td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
if (err != TD_OK)
- error ("thread_db_get_info: cannot get thread info: %s",
+ error ("thread_db_get_info: cannot get thread info: %s",
thread_db_err_str (err));
thread_info->private->ti_valid = 1;
handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
if (handle == NULL)
{
- fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
+ fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
LIBTHREAD_DB_SO, dlerror ());
- fprintf_filtered (gdb_stderr,
+ fprintf_filtered (gdb_stderr,
"GDB will not be able to debug pthreads.\n\n");
return 0;
}
break;
}
- quit:
+quit:
if (target_new_objfile_chain)
target_new_objfile_chain (objfile);
}
/* ...and perform the remaining initialization steps. */
enable_thread_event_reporting ();
- thread_db_find_new_threads();
+ thread_db_find_new_threads ();
}
static void
err = td_thr_get_info_p (msg.th_p, &ti);
if (err != TD_OK)
- error ("check_event: cannot get thread info: %s",
+ error ("check_event: cannot get thread info: %s",
thread_db_err_str (err));
ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
static int
thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
- struct mem_attrib *attrib,
- struct target_ops *target)
+ struct mem_attrib *attrib, struct target_ops *target)
{
struct cleanup *old_chain = save_inferior_ptid ();
int xfer;
inferior_ptid = lwp_from_thread (inferior_ptid);
}
- xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, target);
+ xfer =
+ target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib,
+ target);
do_cleanups (old_chain);
return xfer;
if (regno != -1)
{
- char raw[MAX_REGISTER_RAW_SIZE];
+ char raw[MAX_REGISTER_SIZE];
deprecated_read_register_gen (regno, raw);
thread_db_fetch_registers (-1);
proc_handle.pid = 0;
target_beneath->to_mourn_inferior ();
+
+ /* Detach thread_db target ops if not dealing with a statically
+ linked threaded program. This allows a corefile to be debugged
+ after finishing debugging of a threaded program. At present,
+ debugging a statically-linked threaded program is broken, but
+ the check is added below in the event that it is fixed in the
+ future. */
+ if (!keep_thread_db)
+ {
+ unpush_target (&thread_db_ops);
+ using_thread_db = 0;
+ }
}
static int
thread_info = find_thread_pid (ptid);
thread_db_map_id2thr (thread_info, 0);
- if (! thread_info->private->th_valid)
+ if (!thread_info->private->th_valid)
return 0;
err = td_thr_validate_p (&thread_info->private->th);
if (err != TD_OK)
return 0;
- if (! thread_info->private->ti_valid)
+ if (!thread_info->private->ti_valid)
{
- err = td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
+ err =
+ td_thr_get_info_p (&thread_info->private->th,
+ &thread_info->private->ti);
if (err != TD_OK)
return 0;
thread_info->private->ti_valid = 1;
err = td_thr_get_info_p (th_p, &ti);
if (err != TD_OK)
- error ("find_new_threads_callback: cannot get thread info: %s",
+ error ("find_new_threads_callback: cannot get thread info: %s",
thread_db_err_str (err));
if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
thread_info = find_thread_pid (ptid);
thread_db_map_id2thr (thread_info, 0);
- if (! thread_info->private->th_valid)
+ if (!thread_info->private->th_valid)
{
- snprintf (buf, sizeof (buf), "Thread %ld (Missing)", GET_THREAD (ptid));
+ snprintf (buf, sizeof (buf), "Thread %ld (Missing)",
+ GET_THREAD (ptid));
return buf;
}
else
{
snprintf (buf, sizeof (buf), "Thread %ld (%s)",
- (long) ti_p->ti_tid, thread_db_state_str (ti_p->ti_state));
+ (long) ti_p->ti_tid,
+ thread_db_state_str (ti_p->ti_state));
}
return buf;
static CORE_ADDR
thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile,
- CORE_ADDR offset)
+ CORE_ADDR offset)
{
if (is_thread (ptid))
{
struct thread_info *thread_info;
/* glibc doesn't provide the needed interface. */
- if (! td_thr_tls_get_addr_p)
- error ("Cannot find thread-local variables in this thread library.");
+ if (!td_thr_tls_get_addr_p)
+ error ("Cannot find thread-local variables in this thread library.");
/* Get the address of the link map for this objfile. */
lm = svr4_fetch_objfile_link_map (objfile);
/* Whoops, we couldn't find one. Bail out. */
if (!lm)
- {
- if (objfile_is_library)
- error ("Cannot find shared library `%s' link_map in dynamic"
+ {
+ if (objfile_is_library)
+ error ("Cannot find shared library `%s' link_map in dynamic"
" linker's module list", objfile->name);
else
- error ("Cannot find executable file `%s' link_map in dynamic"
+ error ("Cannot find executable file `%s' link_map in dynamic"
" linker's module list", objfile->name);
}
#ifdef THREAD_DB_HAS_TD_NOTALLOC
/* The memory hasn't been allocated, yet. */
if (err == TD_NOTALLOC)
- {
- /* Now, if libthread_db provided the initialization image's
- address, we *could* try to build a non-lvalue value from
- the initialization image. */
- if (objfile_is_library)
- error ("The inferior has not yet allocated storage for"
- " thread-local variables in\n"
- "the shared library `%s'\n"
- "for the thread %ld",
+ {
+ /* Now, if libthread_db provided the initialization image's
+ address, we *could* try to build a non-lvalue value from
+ the initialization image. */
+ if (objfile_is_library)
+ error ("The inferior has not yet allocated storage for"
+ " thread-local variables in\n"
+ "the shared library `%s'\n"
+ "for the thread %ld",
objfile->name, (long) GET_THREAD (ptid));
- else
- error ("The inferior has not yet allocated storage for"
- " thread-local variables in\n"
- "the executable `%s'\n"
- "for the thread %ld",
+ else
+ error ("The inferior has not yet allocated storage for"
+ " thread-local variables in\n"
+ "the executable `%s'\n"
+ "for the thread %ld",
objfile->name, (long) GET_THREAD (ptid));
}
#endif
error ("Cannot find thread-local storage for thread %ld, "
"shared library %s:\n%s",
(long) GET_THREAD (ptid),
- objfile->name,
- thread_db_err_str (err));
+ objfile->name, thread_db_err_str (err));
else
error ("Cannot find thread-local storage for thread %ld, "
"executable file %s:\n%s",
(long) GET_THREAD (ptid),
- objfile->name,
- thread_db_err_str (err));
+ objfile->name, thread_db_err_str (err));
}
/* Cast assuming host == target. Joy. */
}
if (target_beneath->to_get_thread_local_address)
- return target_beneath->to_get_thread_local_address (ptid, objfile, offset);
+ return target_beneath->to_get_thread_local_address (ptid, objfile,
+ offset);
error ("Cannot find thread-local values on this target.");
}