PERFORCE change 60189 for review
David Xu
davidxu at FreeBSD.org
Sat Aug 21 03:35:35 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=60189
Change 60189 by davidxu at davidxu_alona on 2004/08/21 10:34:57
Add code to support .core for threaded program.
Affected files ...
.. //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#21 edit
Differences ...
==== //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#21 (text+ko) ====
@@ -27,6 +27,8 @@
#include "thread_db.h"
#include "bfd.h"
+#include "elf-bfd.h"
+#include "gdbcore.h"
#include "gdbthread.h"
#include "inferior.h"
#include "symfile.h"
@@ -51,7 +53,12 @@
extern struct target_ops child_ops;
/* This module's target vector. */
-static struct target_ops thread_db_ops;
+static struct target_ops fbsd_thread_ops;
+static struct target_ops fbsd_core_ops;
+
+/* Saved copy of orignal core_ops */
+static struct target_ops orig_core_ops;
+extern struct target_ops core_ops;
/* Pointer to the next function on the objfile event chain. */
static void (*target_new_objfile_chain) (struct objfile *objfile);
@@ -60,7 +67,9 @@
static int fbsd_thread_present;
/* Non-zero if we're using this module's target vector. */
-static int using_thread_db;
+static int fbsd_thread_active;
+
+static int fbsd_thread_core = 0;
/* Non-zero if we have to keep this module's target vector active
across re-runs. */
@@ -123,7 +132,6 @@
/* Prototypes for local functions. */
static void fbsd_thread_find_new_threads (void);
static int fbsd_thread_alive (ptid_t ptid);
-static void fbsd_thread_activate(void);
/* Building process ids. */
@@ -227,7 +235,7 @@
gdb_assert (IS_LWP (ptid));
- if (using_thread_db)
+ if (fbsd_thread_active)
{
err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
if (err == TD_OK)
@@ -243,11 +251,30 @@
return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid));
}
+static void
+fbsd_core_get_first_lwp (bfd *abfd, asection *asect, void *obj)
+{
+ if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
+ return;
+
+ if (*(lwpid_t *)obj != 0)
+ return;
+
+ *(lwpid_t *)obj = atoi (bfd_section_name (abfd, asect) + 5);
+}
+
static long
get_current_lwp (int pid)
{
struct ptrace_lwpinfo pl;
+ lwpid_t lwpid;
+ if (!target_has_execution)
+ {
+ lwpid = 0;
+ bfd_map_over_sections (core_bfd, fbsd_core_get_first_lwp, &lwpid);
+ return lwpid;
+ }
if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof(pl)))
perror_with_name("PT_LWPINFO");
@@ -271,6 +298,27 @@
}
static void
+fbsd_thread_activate (void)
+{
+ fbsd_thread_active = 1;
+ init_thread_list();
+ fbsd_thread_find_new_threads ();
+ get_current_thread ();
+}
+
+static void
+fbsd_thread_deactivate (void)
+{
+ td_ta_delete_p (thread_agent);
+
+ inferior_ptid = pid_to_ptid (proc_handle.pid);
+ proc_handle.pid = 0;
+ fbsd_thread_active = 0;
+ fbsd_thread_present = 0;
+ init_thread_list ();
+}
+
+static void
fbsd_thread_new_objfile (struct objfile *objfile)
{
td_err_e err;
@@ -281,10 +329,10 @@
{
/* All symbols have been discarded. If the thread_db target is
active, deactivate it now. */
- if (using_thread_db)
+ if (fbsd_thread_active)
{
gdb_assert (proc_handle.pid == 0);
- using_thread_db = 0;
+ fbsd_thread_active = 0;
}
goto quit;
@@ -293,7 +341,7 @@
if (!child_suppress_run)
goto quit;
- if (using_thread_db)
+ if (fbsd_thread_active)
/* Nothing to do. The thread library was already detected and the
target vector was already activated. */
goto quit;
@@ -318,16 +366,15 @@
/* We can only poke around if there actually is a child process.
If there is no child process alive, postpone the steps below
until one has been created. */
- if (proc_handle.pid != 0)
+ if (fbsd_thread_core == 0 && proc_handle.pid != 0)
{
- push_target(&thread_db_ops);
+ push_target(&fbsd_thread_ops);
fbsd_thread_activate();
}
else
{
td_ta_delete_p(thread_agent);
thread_agent = NULL;
- printf_filtered("%s postpone processing\n", __func__);
}
break;
@@ -345,23 +392,41 @@
static void
fbsd_thread_attach (char *args, int from_tty)
{
+ fbsd_thread_core = 0;
+
child_ops.to_attach (args, from_tty);
- /* Destroy thread info; it's no longer valid. */
- init_thread_list ();
+ /* Must get symbols from solibs before libthread_db can run! */
+ SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
+
+ if (fbsd_thread_present && !fbsd_thread_active)
+ push_target(&fbsd_thread_ops);
+}
- /* The child process is now the actual multi-threaded
- program. Snatch its process ID... */
- proc_handle.pid = GET_PID (inferior_ptid);
+static void
+fbsd_thread_post_attach (int pid)
+{
+ child_ops.to_post_attach (pid);
- /* ...and perform the remaining initialization steps. */
- fbsd_thread_find_new_threads();
- get_current_thread ();
+ if (fbsd_thread_present && !fbsd_thread_active)
+ {
+ proc_handle.pid = GET_PID (inferior_ptid);
+ fbsd_thread_activate ();
+ }
}
static void
fbsd_thread_detach (char *args, int from_tty)
{
+ fbsd_thread_deactivate ();
+ unpush_target (&fbsd_thread_ops);
+
+ /* Clear gdb solib information and symbol file
+ cache, so that after detach and re-attach, new_objfile
+ hook will be called */
+
+ clear_solib();
+ symbol_file_clear(0);
proc_handle.pid = 0;
child_ops.to_detach (args, from_tty);
}
@@ -401,7 +466,7 @@
GET_THREAD(inferior_ptid));
#endif
- if (!using_thread_db)
+ if (!fbsd_thread_active)
{
child_ops.to_resume (ptid, step, signo);
return;
@@ -523,17 +588,32 @@
fbsd_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
struct mem_attrib *attrib, struct target_ops *target)
{
- return child_ops.to_xfer_memory (memaddr, myaddr, len, write,
- attrib, target);
+ int err;
+
+ if (target_has_execution)
+ err = child_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
+ target);
+ else
+ err = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
+ target);
+
+ return (err);
}
static void
fbsd_lwp_fetch_registers (int regno)
{
+ struct cleanup *old_chain;
gregset_t gregs;
fpregset_t fpregs;
lwpid_t lwp;
+ if (!target_has_execution)
+ {
+ orig_core_ops.to_fetch_registers (-1);
+ return;
+ }
+
lwp = GET_LWP (inferior_ptid);
if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1)
@@ -679,19 +759,10 @@
}
static void
-fbsd_thread_activate (void)
-{
- using_thread_db = 1;
- init_thread_list();
- fbsd_thread_find_new_threads ();
- get_current_thread ();
-}
-
-static void
fbsd_thread_create_inferior (char *exec_file, char *allargs, char **env)
{
- if (fbsd_thread_present && !using_thread_db)
- push_target(&thread_db_ops);
+ if (fbsd_thread_present && !fbsd_thread_active)
+ push_target(&fbsd_thread_ops);
child_ops.to_create_inferior (exec_file, allargs, env);
}
@@ -699,7 +770,7 @@
static void
fbsd_thread_post_startup_inferior (ptid_t ptid)
{
- if (fbsd_thread_present && !using_thread_db)
+ if (fbsd_thread_present && !fbsd_thread_active)
{
/*
* The child process is now the actual multi-threaded
@@ -723,6 +794,23 @@
child_ops.to_mourn_inferior ();
}
+static void
+fbsd_core_check_lwp (bfd *abfd, asection *asect, void *obj)
+{
+ lwpid_t lwp;
+
+ if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
+ return;
+
+ /* already found */
+ if (*(lwpid_t *)obj == 0)
+ return;
+
+ lwp = atoi (bfd_section_name (abfd, asect) + 5);
+ if (*(lwpid_t *)obj == lwp)
+ *(lwpid_t *)obj = 0;
+}
+
static int
fbsd_thread_alive (ptid_t ptid)
{
@@ -730,6 +818,7 @@
td_thrinfo_t ti;
td_err_e err;
gregset_t gregs;
+ lwpid_t lwp;
if (IS_THREAD (ptid))
{
@@ -753,7 +842,7 @@
return 1;
}
- if (using_thread_db)
+ if (fbsd_thread_active)
{
err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
@@ -765,10 +854,23 @@
return 0;
}
+ if (!target_has_execution)
+ {
+ lwp = GET_LWP (ptid);
+ bfd_map_over_sections (core_bfd, fbsd_core_check_lwp, &lwp);
+ return (lwp == 0);
+ }
+
/* check lwp in kernel */
return ptrace (PT_GETREGS, GET_LWP (ptid), (caddr_t)&gregs, 0) == 0;
}
+static void
+fbsd_thread_files_info (struct target_ops *ignore)
+{
+ child_ops.to_files_info (ignore);
+}
+
static int
find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
{
@@ -784,11 +886,10 @@
if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
return 0;
- ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
+ ptid = BUILD_THREAD (ti.ti_tid, proc_handle.pid);
if (!in_thread_list (ptid))
add_thread (ptid);
-
return 0;
}
@@ -797,7 +898,7 @@
{
td_err_e err;
- if (!using_thread_db)
+ if (!fbsd_thread_active)
return;
/* Iterate over all user-space threads to discover new threads. */
@@ -922,42 +1023,136 @@
static void
fbsd_thread_tsd_cmd (char *exp, int from_tty)
{
- if (using_thread_db)
+ if (fbsd_thread_active)
td_ta_tsd_iter_p (thread_agent, tsd_cb, NULL);
}
+static int
+ignore (CORE_ADDR addr, char *contents)
+{
+ return 0;
+}
+
+static void
+fbsd_core_open (char *filename, int from_tty)
+{
+ int err;
+
+ fbsd_thread_core = 1;
+
+ orig_core_ops.to_open (filename, from_tty);
+
+ if (fbsd_thread_present)
+ {
+ err = td_ta_new_p (&proc_handle, &thread_agent);
+ if (err == TD_OK)
+ {
+ proc_handle.pid = elf_tdata (core_bfd)->core_pid;
+ fbsd_thread_activate ();
+ }
+ else
+ error ("fbsd_core_open: td_open: %s", thread_db_err_str (err));
+ }
+}
+
+static void
+fbsd_core_close (int quitting)
+{
+ orig_core_ops.to_close (quitting);
+}
+
+static void
+fbsd_core_detach (char *args, int from_tty)
+{
+ if (fbsd_thread_active)
+ fbsd_thread_deactivate ();
+ unpush_target (&fbsd_thread_ops);
+ orig_core_ops.to_detach (args, from_tty);
+
+ /* Clear gdb solib information and symbol file
+ cache, so that after detach and re-attach, new_objfile
+ hook will be called */
+ clear_solib();
+ symbol_file_clear(0);
+}
+
+static void
+fbsd_core_files_info (struct target_ops *ignore)
+{
+ orig_core_ops.to_files_info (ignore);
+}
+
+static void
+init_fbsd_core_ops (void)
+{
+ fbsd_core_ops.to_shortname = "FreeBSD-core";
+ fbsd_core_ops.to_longname = "FreeBSD core thread.";
+ fbsd_core_ops.to_doc = "FreeBSD thread support for core files.";
+ fbsd_core_ops.to_open = fbsd_core_open;
+ fbsd_core_ops.to_close = fbsd_core_close;
+ fbsd_core_ops.to_attach = 0;
+ fbsd_core_ops.to_post_attach = 0;
+ fbsd_core_ops.to_detach = fbsd_core_detach;
+ /* fbsd_core_ops.to_resume = 0; */
+ /* fbsd_core_ops.to_wait = 0; */
+ fbsd_core_ops.to_fetch_registers = fbsd_thread_fetch_registers;
+ /* fbsd_core_ops.to_store_registers = 0; */
+ /* fbsd_core_ops.to_prepare_to_store = 0; */
+ fbsd_core_ops.to_xfer_memory = fbsd_thread_xfer_memory;
+ fbsd_core_ops.to_files_info = fbsd_core_files_info;
+ fbsd_core_ops.to_insert_breakpoint = ignore;
+ fbsd_core_ops.to_remove_breakpoint = ignore;
+ /* fbsd_core_ops.to_lookup_symbol = 0; */
+ fbsd_core_ops.to_create_inferior = fbsd_thread_create_inferior;
+ fbsd_core_ops.to_stratum = core_stratum;
+ fbsd_core_ops.to_has_all_memory = 0;
+ fbsd_core_ops.to_has_memory = 1;
+ fbsd_core_ops.to_has_stack = 1;
+ fbsd_core_ops.to_has_registers = 1;
+ fbsd_core_ops.to_has_execution = 0;
+ fbsd_core_ops.to_has_thread_control = tc_none;
+ fbsd_core_ops.to_thread_alive = fbsd_thread_alive;
+ fbsd_core_ops.to_pid_to_str = fbsd_thread_pid_to_str;
+ fbsd_core_ops.to_find_new_threads = fbsd_thread_find_new_threads;
+ fbsd_core_ops.to_sections = 0;
+ fbsd_core_ops.to_sections_end = 0;
+ fbsd_core_ops.to_magic = OPS_MAGIC;
+}
+
static void
-init_thread_db_ops (void)
+init_fbsd_thread_ops (void)
{
- thread_db_ops.to_shortname = "multi-thread";
- thread_db_ops.to_longname = "multi-threaded child process.";
- thread_db_ops.to_doc = "Threads and pthreads support.";
- thread_db_ops.to_attach = fbsd_thread_attach;
- thread_db_ops.to_detach = fbsd_thread_detach;
- thread_db_ops.to_resume = fbsd_thread_resume;
- thread_db_ops.to_wait = fbsd_thread_wait;
- thread_db_ops.to_fetch_registers = fbsd_thread_fetch_registers;
- thread_db_ops.to_store_registers = fbsd_thread_store_registers;
- thread_db_ops.to_xfer_memory = fbsd_thread_xfer_memory;
- thread_db_ops.to_kill = fbsd_thread_kill;
- thread_db_ops.to_create_inferior = fbsd_thread_create_inferior;
- thread_db_ops.to_post_startup_inferior = fbsd_thread_post_startup_inferior;
- thread_db_ops.to_mourn_inferior = fbsd_thread_mourn_inferior;
- thread_db_ops.to_can_run = fbsd_thread_can_run;
- thread_db_ops.to_thread_alive = fbsd_thread_alive;
- thread_db_ops.to_find_new_threads = fbsd_thread_find_new_threads;
- thread_db_ops.to_pid_to_str = fbsd_thread_pid_to_str;
- thread_db_ops.to_stratum = thread_stratum;
- thread_db_ops.to_has_thread_control = tc_none;
- thread_db_ops.to_has_all_memory = 1;
- thread_db_ops.to_has_memory = 1;
- thread_db_ops.to_has_stack = 1;
- thread_db_ops.to_has_registers = 1;
- thread_db_ops.to_has_execution = 1;
- 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;
+ fbsd_thread_ops.to_shortname = "freebsd-threads";
+ fbsd_thread_ops.to_longname = "FreeBSD multithreaded child process.";
+ fbsd_thread_ops.to_doc = "FreeBSD threads support.";
+ fbsd_thread_ops.to_attach = fbsd_thread_attach;
+ fbsd_thread_ops.to_detach = fbsd_thread_detach;
+ fbsd_thread_ops.to_post_attach = fbsd_thread_post_attach;
+ fbsd_thread_ops.to_resume = fbsd_thread_resume;
+ fbsd_thread_ops.to_wait = fbsd_thread_wait;
+ fbsd_thread_ops.to_fetch_registers = fbsd_thread_fetch_registers;
+ fbsd_thread_ops.to_store_registers = fbsd_thread_store_registers;
+ fbsd_thread_ops.to_xfer_memory = fbsd_thread_xfer_memory;
+ fbsd_thread_ops.to_files_info = fbsd_thread_files_info;
+ fbsd_thread_ops.to_kill = fbsd_thread_kill;
+ fbsd_thread_ops.to_create_inferior = fbsd_thread_create_inferior;
+ fbsd_thread_ops.to_post_startup_inferior = fbsd_thread_post_startup_inferior;
+ fbsd_thread_ops.to_mourn_inferior = fbsd_thread_mourn_inferior;
+ fbsd_thread_ops.to_can_run = fbsd_thread_can_run;
+ fbsd_thread_ops.to_thread_alive = fbsd_thread_alive;
+ fbsd_thread_ops.to_find_new_threads = fbsd_thread_find_new_threads;
+ fbsd_thread_ops.to_pid_to_str = fbsd_thread_pid_to_str;
+ fbsd_thread_ops.to_stratum = thread_stratum;
+ fbsd_thread_ops.to_has_thread_control = tc_none;
+ fbsd_thread_ops.to_has_all_memory = 1;
+ fbsd_thread_ops.to_has_memory = 1;
+ fbsd_thread_ops.to_has_stack = 1;
+ fbsd_thread_ops.to_has_registers = 1;
+ fbsd_thread_ops.to_has_execution = 1;
+ fbsd_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ fbsd_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ fbsd_thread_ops.to_get_thread_local_address = fbsd_thread_get_local_address;
+ fbsd_thread_ops.to_magic = OPS_MAGIC;
}
static int
@@ -1047,14 +1242,22 @@
return 1;
}
+/* we suppress the call to add_target of core_ops in corelow because
+ if there are two targets in the stratum core_stratum, find_core_target
+ won't know which one to return. see corelow.c for an additonal
+ comment on coreops_suppress_target. */
+
+int coreops_suppress_target = 1;
+
void
_initialize_thread_db (void)
{
- /* Only initialize the module if we can load libthread_db. */
+ init_fbsd_thread_ops ();
+ init_fbsd_core_ops ();
+
if (thread_db_load ())
{
- init_thread_db_ops ();
- add_target (&thread_db_ops);
+ add_target (&fbsd_thread_ops);
/* "thread tsd" command */
add_cmd ("tsd", class_run, fbsd_thread_tsd_cmd,
@@ -1062,15 +1265,24 @@
"for the process.\n",
&thread_cmd_list);
+ memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
+ memcpy (&core_ops, &fbsd_core_ops, sizeof (struct target_ops));
+ add_target (&core_ops);
+
/* Add ourselves to objfile event chain. */
target_new_objfile_chain = target_new_objfile_hook;
target_new_objfile_hook = fbsd_thread_new_objfile;
+
+ child_suppress_run = 1;
}
else
{
- printf_filtered("%s: can not load %s.\n", __func__, LIBTHREAD_DB_SO);
+ fprintf_unfiltered (gdb_stderr,
+ "[GDB will not be able to debug user-mode threads: %s]\n", dlerror());
+
+ /* allow the user to debug non-threaded core files */
+ add_target (&core_ops);
}
- child_suppress_run = 1;
}
/* proc service functions */
More information about the p4-projects
mailing list