X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fthread-db.c;h=78bc6434076a0b6de675d2348d11a365736d6515;hb=29709017e835906e3e95bc230d393331636234e1;hp=f3d57a54d622eb323061d34a023fcb81dca058a0;hpb=0d62e5e8077eecf77e9b7b5dc0d2689d051a3ab3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c index f3d57a54d6..78bc643407 100644 --- a/gdb/gdbserver/thread-db.c +++ b/gdb/gdbserver/thread-db.c @@ -1,5 +1,5 @@ /* Thread management interface, for the remote server for GDB. - Copyright 2002 + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by MontaVista Software. @@ -18,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "server.h" @@ -31,19 +31,7 @@ extern int debug_threads; #include #endif -/* Correct for all GNU/Linux targets (for quite some time). */ -#define GDB_GREGSET_T elf_gregset_t -#define GDB_FPREGSET_T elf_fpregset_t - -#ifndef HAVE_ELF_FPREGSET_T -/* Make sure we have said types. Not all platforms bring in - via . */ -#ifdef HAVE_LINUX_ELF_H -#include -#endif -#endif - -#include "../gdb_proc_service.h" +#include "gdb_proc_service.h" /* Structure that identifies the child process for the interface. */ @@ -103,6 +91,10 @@ thread_db_err_str (td_err_e err) return "only part of register set was written/read"; case TD_NOXREGS: return "X register set not available for this thread"; +#ifdef HAVE_TD_VERSION + case TD_VERSION: + return "version mismatch between libthread_db and libpthread"; +#endif default: snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err); return buf; @@ -274,6 +266,7 @@ found: process->lwpid = ti_p->ti_lid; process->thread_known = 1; + process->th = *th_p; err = td_thr_event_enable (th_p, 1); if (err != TD_OK) error ("Cannot enable thread event reporting for %d: %s", @@ -312,13 +305,68 @@ thread_db_find_new_threads (void) error ("Cannot find new threads: %s", thread_db_err_str (err)); } +/* Cache all future symbols that thread_db might request. We can not + request symbols at arbitrary states in the remote protocol, only + when the client tells us that new symbols are available. So when + we load the thread library, make sure to check the entire list. */ + +static void +thread_db_look_up_symbols (void) +{ + const char **sym_list = td_symbol_list (); + CORE_ADDR unused; + + for (sym_list = td_symbol_list (); *sym_list; sym_list++) + look_up_one_symbol (*sym_list, &unused); +} + +int +thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset, + CORE_ADDR load_module, CORE_ADDR *address) +{ +#if HAVE_TD_THR_TLS_GET_ADDR + psaddr_t addr; + td_err_e err; + struct process_info *process; + + process = get_thread_process (thread); + if (!process->thread_known) + return TD_NOTHR; + + err = td_thr_tls_get_addr (&process->th, (psaddr_t) load_module, offset, + &addr); + if (err == TD_OK) + { + *address = (CORE_ADDR) addr; + return 0; + } + else + return err; +#else + return -1; +#endif +} + int thread_db_init () { int err; + /* FIXME drow/2004-10-16: This is the "overall process ID", which + GNU/Linux calls tgid, "thread group ID". When we support + attaching to threads, the original thread may not be the correct + thread. We would have to get the process ID from /proc for NPTL. + For LinuxThreads we could do something similar: follow the chain + of parent processes until we find the highest one we're attached + to, and use its tgid. + + This isn't the only place in gdbserver that assumes that the first + process in the list is the thread group leader. */ proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id; + /* Allow new symbol lookups. */ + all_symbols_looked_up = 0; + err = td_ta_new (&proc_handle, &thread_agent); switch (err) { @@ -332,10 +380,13 @@ thread_db_init () if (thread_db_enable_reporting () == 0) return 0; thread_db_find_new_threads (); + thread_db_look_up_symbols (); + all_symbols_looked_up = 1; return 1; default: - warning ("error initializing thread_db library."); + warning ("error initializing thread_db library: %s", + thread_db_err_str (err)); } return 0;