Not yet submitted upstream. This requires some serious thinking about. If the target stack worked in any logical way, this wouldn't be necessary... ending up with roughly: thread_stratum: thread-db (silent reference to lin-lwp) core_stratum: corelow exec_stratum: exec dummy_stratum: dummy just makes no sense. This patch fixes debugging threaded applications which are statically linked without breaking debugging threaded core files. It also fixes the PIDs in generate-core-file'd corefiles. Mostly. diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/corelow.c gdb-5.2.debian90.cvs20021120/gdb/corelow.c --- o/gdb-5.2.debian90.cvs20021120/gdb/corelow.c 2002-09-18 13:23:15.000000000 -0400 +++ gdb-5.2.debian90.cvs20021120/gdb/corelow.c 2002-12-03 14:03:32.000000000 -0500 @@ -350,7 +350,7 @@ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); - if (ontop) + if (ontop || 1) { /* Fetch all registers from core file. */ target_fetch_registers (-1); diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/target.c gdb-5.2.debian90.cvs20021120/gdb/target.c --- o/gdb-5.2.debian90.cvs20021120/gdb/target.c 2002-09-18 13:23:22.000000000 -0400 +++ gdb-5.2.debian90.cvs20021120/gdb/target.c 2002-12-03 14:06:07.000000000 -0500 @@ -1589,6 +1589,7 @@ dummy_target.to_find_memory_regions = dummy_find_memory_regions; dummy_target.to_make_corefile_notes = dummy_make_corefile_notes; dummy_target.to_magic = OPS_MAGIC; + cleanup_target (&dummy_target); } --- gdb-5.3.20030606/gdb/thread-db.c.orig 2003-06-08 11:54:59.000000000 -0400 +++ gdb-5.3.20030606/gdb/thread-db.c 2003-06-08 11:55:05.000000000 -0400 @@ -59,6 +59,31 @@ static void (*target_new_objfile_chain) /* Non-zero if we're using this module's target vector. */ static int using_thread_db; +/* Macros to pass an event to the next target if we should not be handling it + here in the thread_stratum. */ +#define FIND_NEXT_TARGET(METHOD_NAME) \ + struct target_ops *next_target = &thread_db_ops; \ + while (1) \ + { \ + next_target = find_target_beneath (next_target); \ + if (next_target->METHOD_NAME != NULL) \ + break; \ + } + +#define MAYBE_HAND_DOWN(METHOD_NAME,ARGS) \ + if (proc_handle.pid == 0) \ + { \ + FIND_NEXT_TARGET (METHOD_NAME); \ + (*next_target->METHOD_NAME) ARGS; \ + return; \ + } +#define MAYBE_HAND_DOWN_RETURN(METHOD_NAME,ARGS) \ + if (proc_handle.pid == 0) \ + { \ + FIND_NEXT_TARGET (METHOD_NAME); \ + return (*next_target->METHOD_NAME) ARGS; \ + } + /* Non-zero if we have to keep this module's target vector active across re-runs. */ static int keep_thread_db; @@ -587,9 +612,7 @@ thread_db_new_objfile (struct objfile *o { td_err_e err; - /* Don't attempt to use thread_db on targets which can not run - (core files). */ - if (objfile == NULL || !target_has_execution) + if (objfile == NULL) { /* All symbols have been discarded. If the thread_db target is active, deactivate it now. */ @@ -613,7 +636,10 @@ thread_db_new_objfile (struct objfile *o /* Initialize the structure that identifies the child process. Note that at this point there is no guarantee that we actually have a child process. */ - proc_handle.pid = GET_PID (inferior_ptid); + if (target_has_execution) + proc_handle.pid = GET_PID (inferior_ptid); + else + proc_handle.pid = 0; /* Now attempt to open a connection to the thread library. */ err = td_ta_new_p (&proc_handle, &thread_agent); @@ -881,6 +907,9 @@ thread_db_xfer_memory (CORE_ADDR memaddr struct cleanup *old_chain = save_inferior_ptid (); int xfer; + MAYBE_HAND_DOWN_RETURN (to_xfer_memory, (memaddr, myaddr, len, write, + attrib, target)); + if (is_thread (inferior_ptid)) { /* FIXME: This seems to be necessary to make sure breakpoints @@ -907,6 +936,10 @@ thread_db_fetch_registers (int regno) gdb_prfpregset_t fpregset; td_err_e err; + MAYBE_HAND_DOWN (to_fetch_registers, (regno)); + + MAYBE_HAND_DOWN (to_store_registers, (regno)); + if (!is_thread (inferior_ptid)) { /* Pass the request to the target beneath us. */ @@ -1040,6 +1073,8 @@ thread_db_thread_alive (ptid_t ptid) td_thrhandle_t th; td_err_e err; + MAYBE_HAND_DOWN_RETURN (to_thread_alive, (ptid)); + if (is_thread (ptid)) { struct thread_info *thread_info; @@ -1104,6 +1139,8 @@ thread_db_find_new_threads (void) { td_err_e err; + MAYBE_HAND_DOWN (to_find_new_threads, ()); + /* Iterate over all user-space threads to discover new threads. */ err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, @@ -1115,6 +1152,8 @@ thread_db_find_new_threads (void) static char * thread_db_pid_to_str (ptid_t ptid) { + MAYBE_HAND_DOWN_RETURN (to_pid_to_str, (ptid)); + if (is_thread (ptid)) { static char buf[64];