diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-08-08 22:45:36 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-08-08 22:45:36 +0000 |
commit | be987aa523bc735432ac8fed0b511a46c1ead1c2 (patch) | |
tree | dbf915bfb790aad1b9a3f4110c354865e0b17889 /gnu/usr.bin | |
parent | be9db1f7cb124c010333e8999a1e34d600b39974 (diff) | |
download | FreeBSD-src-be987aa523bc735432ac8fed0b511a46c1ead1c2.zip FreeBSD-src-be987aa523bc735432ac8fed0b511a46c1ead1c2.tar.gz |
1. Add some code check if thread suspending or resuming is failed.
2. Add code to retrieve thread tls address.
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r-- | gnu/usr.bin/gdb/libgdb/Makefile | 2 | ||||
-rw-r--r-- | gnu/usr.bin/gdb/libgdb/fbsd-threads.c | 82 |
2 files changed, 80 insertions, 4 deletions
diff --git a/gnu/usr.bin/gdb/libgdb/Makefile b/gnu/usr.bin/gdb/libgdb/Makefile index 6c41d1a..fc59783 100644 --- a/gnu/usr.bin/gdb/libgdb/Makefile +++ b/gnu/usr.bin/gdb/libgdb/Makefile @@ -37,7 +37,7 @@ SRCS= annotate.c arch-utils.c auxv.c ax-gdb.c ax-general.c bcache.c \ tui-stack.c tui-win.c tui-windata.c tui-wingeneral.c \ tui-winsource.c typeprint.c ui-file.c ui-out.c user-regs.c \ utils.c valarith.c valops.c valprint.c values.c varobj.c \ - wrapper.c ${LIBSRCS} + wrapper.c fbsd-threads.c ${LIBSRCS} GENSRCS= version.c diff --git a/gnu/usr.bin/gdb/libgdb/fbsd-threads.c b/gnu/usr.bin/gdb/libgdb/fbsd-threads.c index 46e1351..c2e6c5f 100644 --- a/gnu/usr.bin/gdb/libgdb/fbsd-threads.c +++ b/gnu/usr.bin/gdb/libgdb/fbsd-threads.c @@ -35,6 +35,7 @@ #include "target.h" #include "regcache.h" #include "gdbcmd.h" +#include "solib-svr4.h" #include <sys/ptrace.h> @@ -109,12 +110,15 @@ static td_err_e (*td_thr_sstep_p) (td_thrhandle_t *th, int step); static td_err_e (*td_ta_tsd_iter_p) (const td_thragent_t *ta, td_key_iter_f *func, void *data); - +static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th, + void *map_address, + size_t offset, void **address); static td_err_e (*td_thr_dbsuspend_p) (const td_thrhandle_t *); static td_err_e (*td_thr_dbresume_p) (const td_thrhandle_t *); /* Prototypes for local functions. */ static void fbsd_thread_find_new_threads (void); +static int fbsd_thread_alive (ptid_t ptid); /* Building process ids. */ @@ -367,13 +371,19 @@ fbsd_thread_detach (char *args, int from_tty) static int suspend_thread_callback (const td_thrhandle_t *th_p, void *data) { - return td_thr_dbsuspend_p (th_p); + int err = td_thr_dbsuspend_p (th_p); + if (err != 0) + printf_filtered("%s %s\n", __func__, thread_db_err_str (err)); + return (err); } static int resume_thread_callback (const td_thrhandle_t *th_p, void *data) { - return td_thr_dbresume_p (th_p); + int err = td_thr_dbresume_p (th_p); + if (err != 0) + printf_filtered("%s %s\n", __func__, thread_db_err_str (err)); + return (err); } static void @@ -496,6 +506,16 @@ fbsd_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) ret = thread_from_lwp (BUILD_LWP (lwp, GET_PID (ret))); if (!in_thread_list (ret)) add_thread (ret); + /* this is a hack, if an event won't cause gdb to stop, for example, + SIGARLM, gdb resumes the process immediatly without setting + inferior_ptid to the new thread returned here, this is a bug + because inferior_ptid may already not exist there, and passing + a none existing thread to fbsd_thread_resume causes error. */ + if (!fbsd_thread_alive (inferior_ptid)) + { + delete_thread (inferior_ptid); + inferior_ptid = ret; + } } return (ret); @@ -816,6 +836,59 @@ fbsd_thread_pid_to_str (ptid_t ptid) return normal_pid_to_str (ptid); } +CORE_ADDR +fbsd_thread_get_local_address(ptid_t ptid, struct objfile *objfile, + CORE_ADDR offset) +{ + td_thrhandle_t th; + void *address; + CORE_ADDR lm; + int ret, is_library = (objfile->flags & OBJF_SHARED); + + if (IS_THREAD (ptid)) + { + if (!td_thr_tls_get_addr_p) + error ("Cannot find thread-local interface in thread_db library."); + + /* Get the address of the link map for this objfile. */ + lm = svr4_fetch_objfile_link_map (objfile); + + /* Couldn't find link map. Bail out. */ + if (!lm) + { + if (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" + " linker's module list", objfile->name); + } + + ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th); + + /* get the address of the variable. */ + ret = td_thr_tls_get_addr_p (&th, (void *) lm, offset, &address); + + if (ret != TD_OK) + { + if (is_library) + error ("Cannot find thread-local storage for thread %ld, " + "shared library %s:\n%s", + (long) GET_THREAD (ptid), + objfile->name, thread_db_err_str (ret)); + 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 (ret)); + } + + /* Cast assuming host == target. */ + return (CORE_ADDR) address; + } + return (0); +} + static int tsd_cb (thread_key_t key, void (*destructor)(void *), void *ignore) { @@ -862,6 +935,7 @@ init_thread_db_ops (void) thread_db_ops.to_has_thread_control = tc_none; thread_db_ops.to_insert_breakpoint = memory_insert_breakpoint; thread_db_ops.to_remove_breakpoint = memory_remove_breakpoint; + thread_db_ops.to_get_thread_local_address = fbsd_thread_get_local_address; thread_db_ops.to_magic = OPS_MAGIC; } @@ -935,6 +1009,8 @@ thread_db_load (void) if (td_thr_dbresume_p == NULL) return 0; + td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"); + /* Initialize the library. */ err = td_init_p (); if (err != TD_OK) |