aboutsummaryrefslogtreecommitdiff
path: root/gdb/thread-db.c
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2004-06-04 21:28:15 +0000
committerJeff Johnston <jjohnstn@redhat.com>2004-06-04 21:28:15 +0000
commitb9b5d7ea4de09f50277394ab1063cbb28d9cdfc9 (patch)
tree44a312000bb8638190c5ceba4ea7d0646274ddd5 /gdb/thread-db.c
parentd4a00f218b16132f13e4364c1b6b34934d31587a (diff)
downloadgdb-b9b5d7ea4de09f50277394ab1063cbb28d9cdfc9.zip
gdb-b9b5d7ea4de09f50277394ab1063cbb28d9cdfc9.tar.gz
gdb-b9b5d7ea4de09f50277394ab1063cbb28d9cdfc9.tar.bz2
2004-06-04 Jeff Johnston <jjohnstn@redhat.com>
* infrun.c (handle_inferior_event): Don't treat an invalid ptid as a new thread event. * thread_db.c (thread_get_info_callback): If the thread is a zombie, return TD_THR_ZOMBIE. * (thread_from_lwp): If thread_get_info_callback returns TD_THR_ZOMBIE, check if the thread is still on the thread list and return a -1 ptid if not found. (thread_db_wait): If thread_from_lwp returns a -1 ptid, then change the status to TARGET_WAITKIND_SPURIOUS.
Diffstat (limited to 'gdb/thread-db.c')
-rw-r--r--gdb/thread-db.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/gdb/thread-db.c b/gdb/thread-db.c
index 9053638..baa9ba6 100644
--- a/gdb/thread-db.c
+++ b/gdb/thread-db.c
@@ -252,7 +252,10 @@ thread_db_state_str (td_thr_state_e state)
THP is a handle to the current thread; if INFOP is not NULL, the
struct thread_info associated with this thread is returned in
- *INFOP. */
+ *INFOP.
+
+ If the thread is a zombie, TD_THR_ZOMBIE is returned. Otherwise,
+ zero is returned to indicate success. */
static int
thread_get_info_callback (const td_thrhandle_t *thp, void *infop)
@@ -271,6 +274,16 @@ thread_get_info_callback (const td_thrhandle_t *thp, void *infop)
thread_ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
thread_info = find_thread_pid (thread_ptid);
+ /* In the case of a zombie thread, don't continue. We don't want to
+ attach to it thinking it is a new thread and we don't want to mark
+ it as valid. */
+ if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
+ {
+ if (infop != NULL)
+ *(struct thread_info **) infop = thread_info;
+ return TD_THR_ZOMBIE;
+ }
+
if (thread_info == NULL)
{
/* New thread. Attach to it now (why wait?). */
@@ -355,7 +368,19 @@ thread_from_lwp (ptid_t ptid)
GET_LWP (ptid), thread_db_err_str (err));
thread_info = NULL;
- thread_get_info_callback (&th, &thread_info);
+
+ /* Fetch the thread info. If we get back TD_THR_ZOMBIE, then the
+ event thread has already died. If another gdb interface has called
+ thread_alive() previously, the thread won't be found on the thread list
+ anymore. In that case, we don't want to process this ptid anymore
+ to avoid the possibility of later treating it as a newly
+ discovered thread id that we should add to the list. Thus,
+ we return a -1 ptid which is also how the thread list marks a
+ dead thread. */
+ if (thread_get_info_callback (&th, &thread_info) == TD_THR_ZOMBIE
+ && thread_info == NULL)
+ return pid_to_ptid (-1);
+
gdb_assert (thread_info && thread_info->private->ti_valid);
return BUILD_THREAD (thread_info->private->ti.ti_tid, GET_PID (ptid));
@@ -950,7 +975,16 @@ thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
if (!ptid_equal (trap_ptid, null_ptid))
trap_ptid = thread_from_lwp (trap_ptid);
- return thread_from_lwp (ptid);
+ /* Change the ptid back into the higher level PID + TID format.
+ If the thread is dead and no longer on the thread list, we will
+ get back a dead ptid. This can occur if the thread death event
+ gets postponed by other simultaneous events. In such a case,
+ we want to just ignore the event and continue on. */
+ ptid = thread_from_lwp (ptid);
+ if (GET_PID (ptid) == -1)
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+
+ return ptid;
}
static int