From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5868 invoked by alias); 14 Aug 2010 19:06:01 -0000 Received: (qmail 5855 invoked by uid 22791); 14 Aug 2010 19:05:59 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 14 Aug 2010 19:05:53 +0000 Received: (qmail 23007 invoked from network); 14 Aug 2010 19:05:51 -0000 Received: from unknown (HELO orlando.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 14 Aug 2010 19:05:51 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: PR corefile/8210: Linux core files should use linux-thread-db.c Date: Sat, 14 Aug 2010 19:06:00 -0000 User-Agent: KMail/1.13.2 (Linux/2.6.33-29-realtime; KDE/4.4.2; x86_64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201008142005.49256.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-08/txt/msg00208.txt.bz2 This enables using the linux-thread-db.c target on top of linux core files. It mainly skips doing things that would go straight to the linux-nat.c target, that only make sense when debugging a live program. Lukily, after skipping those, we end up bypassing all the linux-thread-db.c/linux-nat.c entanglement. Before: (gdb) info threads During symbol reading, incomplete CFI data; unspecified registers (e.g., rax) at 0x7f0f567be3a0. 6 LWP 6785 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 5 LWP 6781 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 4 LWP 6784 0x00007f0f567f2fe3 in select () from /lib/libc.so.6 3 LWP 6783 0x00007f0f567f2fe3 in select () from /lib/libc.so.6 2 LWP 6782 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 * 1 LWP 6780 0x00007f0f567be38d in nanosleep () from /lib/libc.so.6 After: (gdb) info threads During symbol reading, incomplete CFI data; unspecified registers (e.g., rax) at 0x7f0f567be3a0. 6 Thread 0x7f0f5470f710 (LWP 6785) 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 5 Thread 0x7f0f56713710 (LWP 6781) 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 4 Thread 0x7f0f54f10710 (LWP 6784) 0x00007f0f567f2fe3 in select () from /lib/libc.so.6 3 Thread 0x7f0f55711710 (LWP 6783) 0x00007f0f567f2fe3 in select () from /lib/libc.so.6 2 Thread 0x7f0f55f12710 (LWP 6782) 0x00007f0f56d28464 in __lll_lock_wait () from /lib/libpthread.so.0 * 1 Thread 0x7f0f5712a700 (LWP 6780) 0x00007f0f567be38d in nanosleep () from /lib/libc.so.6 I also confirmed that one can now print TLS variables when debugging core files. This will only work when these patches are applied: This is because libthread_db ignores threads that don't match the overall process id that we return in the proc-service's ps_getpid interface. Currently, on linux, we're using a fake PID for core files, which obviously doesn't match what libthread_db expects. The patches behind those links allow GDB to get at the correct PID and stop using a fake one on x86 and x86-64, and leaves the infrastructure in place for other archs. -- Pedro Alves 2010-08-14 Pedro Alves PR corefile/8210 gdb/ * linux-thread-db.c (add_thread_db_info): Skip glibc/BZ5983 workaround on core files. (try_thread_db_load_1): Don't try enabling thread event reporting on core files. (thread_db_load): Allow thread_db on core files. (attach_thread): Don't check thread signals on core files, nor try really attaching to the thread, nor enabling thread event event reporting. (thread_db_detach): Don't try disabing thread event reporting or removing thread event breakpoints when debugging a core file. (find_new_threads_callback): Don't try enabling thread event reporting on core files. (thread_db_find_new_threads_2): Don't look for a stopped lwp when debugging a core file. (thread_db_find_new_threads): Don't update thread cores (processors) when debugging a core (dump). --- gdb/linux-thread-db.c | 83 +++++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 31 deletions(-) Index: src/gdb/linux-thread-db.c =================================================================== --- src.orig/gdb/linux-thread-db.c 2010-08-14 18:40:08.000000000 +0100 +++ src/gdb/linux-thread-db.c 2010-08-14 18:40:03.000000000 +0100 @@ -189,7 +189,11 @@ add_thread_db_info (void *handle) info = xcalloc (1, sizeof (*info)); info->pid = ptid_get_pid (inferior_ptid); info->handle = handle; - info->need_stale_parent_threads_check = 1; + + /* The workaround works by reading from /proc/pid/status, so it is + disabled for core files. */ + if (target_has_execution) + info->need_stale_parent_threads_check = 1; info->next = thread_db_list; thread_db_list = info; @@ -737,7 +741,9 @@ try_thread_db_load_1 (struct thread_db_i if (thread_db_list->next == NULL) push_target (&thread_db_ops); - enable_thread_event_reporting (); + /* Enable event reporting, but not when debugging a core file. */ + if (target_has_execution) + enable_thread_event_reporting (); /* There appears to be a bug in glibc-2.3.6: calls to td_thr_get_info fail with TD_ERR for statically linked executables if td_thr_get_info is @@ -869,13 +875,13 @@ thread_db_load (void) if (info != NULL) return 1; - /* Don't attempt to use thread_db on targets which can not run - (executables not running yet, core files) for now. */ - if (!target_has_execution) + /* Don't attempt to use thread_db on executables not running + yet. */ + if (!target_has_registers) return 0; /* Don't attempt to use thread_db for remote targets. */ - if (!target_can_run (¤t_target)) + if (!(target_can_run (¤t_target) || core_bfd)) return 0; if (thread_db_load_search ()) @@ -1030,13 +1036,15 @@ attach_thread (ptid_t ptid, const td_thr } } - check_thread_signals (); + if (target_has_execution) + check_thread_signals (); if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) return 0; /* A zombie thread -- do not attach. */ /* Under GNU/Linux, we have to attach to each and every thread. */ - if (tp == NULL + if (target_has_execution + && tp == NULL && lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0) return 0; @@ -1061,11 +1069,16 @@ attach_thread (ptid_t ptid, const td_thr info = get_thread_db_info (GET_PID (ptid)); - /* Enable thread event reporting for this thread. */ - err = info->td_thr_event_enable_p (th_p, 1); - if (err != TD_OK) - error (_("Cannot enable thread event reporting for %s: %s"), - target_pid_to_str (ptid), thread_db_err_str (err)); + /* Enable thread event reporting for this thread, except when + debugging a core file. */ + if (target_has_execution) + { + err = info->td_thr_event_enable_p (th_p, 1); + if (err != TD_OK) + error (_("Cannot enable thread event reporting for %s: %s"), + target_pid_to_str (ptid), thread_db_err_str (err)); + } + return 1; } @@ -1097,14 +1110,17 @@ thread_db_detach (struct target_ops *ops if (info) { - disable_thread_event_reporting (info); + if (target_has_execution) + { + disable_thread_event_reporting (info); - /* Delete the old thread event breakpoints. Note that unlike - when mourning, we can remove them here because there's still - a live inferior to poke at. In any case, GDB will not try to - insert anything in the inferior when removing a - breakpoint. */ - remove_thread_event_breakpoints (); + /* Delete the old thread event breakpoints. Note that + unlike when mourning, we can remove them here because + there's still a live inferior to poke at. In any case, + GDB will not try to insert anything in the inferior when + removing a breakpoint. */ + remove_thread_event_breakpoints (); + } delete_thread_db_info (GET_PID (inferior_ptid)); } @@ -1317,7 +1333,7 @@ find_new_threads_callback (const td_thrh if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) return 0; /* A zombie -- ignore. */ - if (ti.ti_tid == 0) + if (ti.ti_tid == 0 && target_has_execution) { /* A thread ID of zero means that this is the main thread, but glibc has not yet initialized thread-local storage and the @@ -1417,19 +1433,23 @@ static void thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new) { td_err_e err; - struct lwp_info *lp; struct thread_db_info *info; int pid = ptid_get_pid (ptid); int i, loop; - /* In linux, we can only read memory through a stopped lwp. */ - ALL_LWPS (lp, ptid) - if (lp->stopped && ptid_get_pid (lp->ptid) == pid) - break; + if (target_has_execution) + { + struct lwp_info *lp; - if (!lp) - /* There is no stopped thread. Bail out. */ - return; + /* In linux, we can only read memory through a stopped lwp. */ + ALL_LWPS (lp, ptid) + if (lp->stopped && ptid_get_pid (lp->ptid) == pid) + break; + + if (!lp) + /* There is no stopped thread. Bail out. */ + return; + } info = get_thread_db_info (GET_PID (ptid)); @@ -1480,8 +1500,9 @@ thread_db_find_new_threads (struct targe thread_db_find_new_threads_1 (inferior_ptid); - iterate_over_lwps (minus_one_ptid /* iterate over all */, - update_thread_core, NULL); + if (target_has_execution) + iterate_over_lwps (minus_one_ptid /* iterate over all */, + update_thread_core, NULL); } static char *