From b9b5d7ea4de09f50277394ab1063cbb28d9cdfc9 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 4 Jun 2004 21:28:15 +0000 Subject: [PATCH] 2004-06-04 Jeff Johnston * 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. --- gdb/ChangeLog | 12 ++++++++++++ gdb/infrun.c | 1 + gdb/thread-db.c | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6e380dbcac..0e830f4be7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2004-06-04 Jeff Johnston + + * 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. + 2004-06-03 Corinna Vinschen * sh-tdep.c (sh3e_sh4_store_return_value): Correctly store diff --git a/gdb/infrun.c b/gdb/infrun.c index 3834cd820b..feb8cbaa34 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1332,6 +1332,7 @@ handle_inferior_event (struct execution_control_state *ecs) /* If it's a new process, add it to the thread database */ ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid) + && !ptid_equal (ecs->ptid, minus_one_ptid) && !in_thread_list (ecs->ptid)); if (ecs->ws.kind != TARGET_WAITKIND_EXITED diff --git a/gdb/thread-db.c b/gdb/thread-db.c index 9053638dfb..baa9ba6e54 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