This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] fix linuxthread debugging WRT zombies with glibc-2.2.3


Problem: When debugging linuxthread programs in a glibc-2.2.3
environment (gdb and app. built with glibc-2.2.3) with
CVS gdb, the thread ("info threads" and "thread N") commands stop
working as soon as any non-detached thread finishes.

Analysis: This is because when a non-detached thread terminates,
it is in the TD_THR_ZOMBIE state.  Michael Snyder's earlier patch
to deal with zombie threads (link below) only looks for TD_THR_UNKNOWN
threads (terminated and detached).  In emails discussing this
problem with Michael, he said the idea was to continue reporting
terminated, un-detached threads to the user (since he/she may like
to know that they're lying around and should be joined).  But a change
in glibc-2.2.3 close to its release caused the TD_THR_ZOMBIE case
scenario I found to fail in gdb, since the linuxthreads_db function
td_ta_map_id2thr() now returns TD_NOTHR instead of TD_OK for
terminated threads, which causes gdb to error().

Heres' the full flow that results in the error:

The prune_threads() call at the top of info_threads_command()
is removing the zombie,
because thread_alive on it returns 0,
because thread_db_thread_alive returns 0 on it,
because td_ta_map_id2thr_p returns TD_NOTHR
because struct _pthread_descr_struct pds pds.p_terminated != 0
In other words, linuxthreads says the thread is terminated,
so gdb is removing it from its list of threads.
Since the thread was removed in prune_threads(),
find_new_threads is trying to add it back, and
calls the same td_ta_map_id2thr_p function which
returns the same TD_NOTHR value, causing the call
to error().

This patch gets gdb thread commands functional again with glibc-2.2.3.
Checked & cleared with Michael Snyder, who started work on
having gdb deal with zombie linuxthreads:
http://sources.redhat.com/ml/gdb-patches/2001-05/msg00423.html



2001-06-29  Ken Whaley  <ken@believe.com>

	* thread-db.c: Check for TD_THR_ZOMBIE in addition to
		 TD_THR_UNKNOWN when looking for defunct zombie threads.
	(attach_thread)
	(thread_db_thread_alive)
	(find_new_threads_callback)


diff -u gdb/thread-db.c.cvs gdb/thread-db.c
--- gdb/thread-db.c.cvs Tue May 22 17:06:15 2001
+++ gdb/thread-db.c     Fri Jun 29 10:13:25 2001
@@ -573,7 +573,7 @@
   tp->private = xmalloc (sizeof (struct private_thread_info));
   tp->private->lwpid = ti_p->ti_lid;

-  if (ti_p->ti_state == TD_THR_UNKNOWN)
+  if ((ti_p->ti_state == TD_THR_UNKNOWN) || (ti_p->ti_state ==
TD_THR_ZOMBIE))
     return;/* A zombie thread that's been joined -- do not attach. */

   /* Under Linux, we have to attach to each and every thread.  */
@@ -915,7 +915,7 @@
       if (err != TD_OK)
        return 0;

-      if (ti.ti_state == TD_THR_UNKNOWN)
+      if ((ti.ti_state == TD_THR_UNKNOWN) || (ti.ti_state ==
TD_THR_ZOMBIE))
        return 0;       /* A zombie thread that's been joined. */

       return 1;
@@ -938,7 +938,7 @@
   if (err != TD_OK)
     error ("Cannot get thread info: %s", thread_db_err_str (err));

-  if (ti.ti_state == TD_THR_UNKNOWN)
+  if ((ti.ti_state == TD_THR_UNKNOWN) || (ti.ti_state == TD_THR_ZOMBIE))
     return 0;  /* A zombie that's been reaped -- ignore. */

   ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));


--
Ken Whaley
ken@believe.com <mailto:ken@believe.com>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]