This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] fix linuxthread debugging WRT zombies with glibc-2.2.3
- To: <gdb-patches at sources dot redhat dot com>
- Subject: [PATCH] fix linuxthread debugging WRT zombies with glibc-2.2.3
- From: "Ken Whaley" <ken at believe dot com>
- Date: Mon, 2 Jul 2001 18:15:49 -0700
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>