From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21090 invoked by alias); 19 Jun 2006 16:56:24 -0000 Received: (qmail 21079 invoked by uid 22791); 19 Jun 2006 16:56:22 -0000 X-Spam-Check-By: sourceware.org Received: from ip-85-160-1-89.eurotel.cz (HELO host0.dyn.jankratochvil.net) (85.160.1.89) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 19 Jun 2006 16:56:18 +0000 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.13.6/8.13.4) with ESMTP id k5JGu9Rq014749 for ; Mon, 19 Jun 2006 18:56:10 +0200 Received: (from lace@localhost) by host0.dyn.jankratochvil.net (8.13.6/8.13.6/Submit) id k5JGu9HT014748 for gdb-patches@sourceware.org; Mon, 19 Jun 2006 18:56:09 +0200 Date: Mon, 19 Jun 2006 16:56:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Fix for 'info threads' crashes if zombie threads exist Message-ID: <20060619165609.GA14691@host0.dyn.jankratochvil.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="IJpNTDwzlM2Ie8A6" Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-06/txt/msg00273.txt.bz2 --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 724 Hi, https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=182116 Steps to Reproduce: 1.Start print-threads within GDB 2.Set a breakpoint in __pthread_unwind 3.Run the program 4.When the program stops at the breakpoint, run `info threads' Patch disables handling of the TD_DEATH notification from __nptl_death_event() and tries to keep the thread in TD_THR_ZOMBIE state as long as possible before its LWP ceases to be. While expecting regressions so far no such was found, statistically it improves some testcases (+24 passes,-14 fails), no negatives. ('longjmp' part not resolved; not reproducible for GDB-CVS) Thread is now debuggable through pthread_exit(3) and the thread terminating code. Regards, Jan Kratochvil --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="gdb-cvs20060619-pthread_exit.patch" Content-length: 2932 Draft patch (for GDB-CVS) proposal for handling+tracing behing pthread_exit(3) Patch disables handling of the TD_DEATH notification from __nptl_death_event() and tries to keep the thread in TD_THR_ZOMBIE state as long as possible before its LWP ceases to be. While expecting regressions so far no such was found, statistically it improves some testcases (+24 passes,-14 fails), no negatives. ('longjmp' part not resolved; not reproducible for GDB-CVS) Index: linux-thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/linux-thread-db.c,v retrieving revision 1.16 diff -u -p -r1.16 linux-thread-db.c --- linux-thread-db.c 5 May 2006 22:42:43 -0000 1.16 +++ linux-thread-db.c 19 Jun 2006 16:27:16 -0000 @@ -541,6 +541,7 @@ enable_thread_event_reporting (void) td_event_emptyset (&events); td_event_addset (&events, TD_CREATE); +#if 0 /* Do not track TD_DEATH to be able to trace pthread_exit(3). */ #ifdef HAVE_GNU_LIBC_VERSION_H /* FIXME: kettenis/2000-04-23: The event reporting facility is broken for TD_DEATH events in glibc 2.1.3, so don't enable it for @@ -550,6 +551,7 @@ enable_thread_event_reporting (void) && (libc_major > 2 || (libc_major == 2 && libc_minor > 1))) #endif td_event_addset (&events, TD_DEATH); +#endif err = td_ta_set_event_p (thread_agent, &events); if (err != TD_OK) @@ -573,6 +575,7 @@ enable_thread_event_reporting (void) return; } +#if 0 /* Do not track TD_DEATH to be able to trace pthread_exit(3). */ /* Set up the thread death event. */ err = enable_thread_event (thread_agent, TD_DEATH, &td_death_bp_addr); if (err != TD_OK) @@ -581,6 +584,7 @@ enable_thread_event_reporting (void) thread_db_err_str (err)); return; } +#endif } static void @@ -1006,6 +1010,9 @@ thread_db_fetch_registers (int regno) } thread_info = find_thread_pid (inferior_ptid); + if (!thread_info) + error (_("Stopped at dead thread %ld; should not happen."), + (long) GET_THREAD (inferior_ptid)); thread_db_map_id2thr (thread_info, 1); err = td_thr_getgregs_p (&thread_info->private->th, gregset); @@ -1127,6 +1134,8 @@ thread_db_thread_alive (ptid_t ptid) struct thread_info *thread_info; thread_info = find_thread_pid (ptid); + if (!thread_info) + return 0; thread_db_map_id2thr (thread_info, 0); if (!thread_info->private->th_valid) return 0; @@ -1145,9 +1154,9 @@ thread_db_thread_alive (ptid_t ptid) thread_info->private->ti_valid = 1; } - if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN - || thread_info->private->ti.ti_state == TD_THR_ZOMBIE) - return 0; /* A zombie thread. */ + /* Never 0 on TD_THR_ZOMBIE to be able to trace pthread_exit(3). */ + if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN) + return 0; /* A disappeared thread. */ return 1; } --IJpNTDwzlM2Ie8A6--