From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9674 invoked by alias); 18 Sep 2007 09:48:24 -0000 Received: (qmail 9657 invoked by uid 22791); 18 Sep 2007 09:48:23 -0000 X-Spam-Check-By: sourceware.org Received: from province.act-europe.fr (HELO province.act-europe.fr) (212.157.227.214) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 18 Sep 2007 09:48:14 +0000 Received: by province.act-europe.fr (Postfix, from userid 560) id 5F86B1662BF; Tue, 18 Sep 2007 11:48:06 +0200 (CEST) Date: Tue, 18 Sep 2007 09:48:00 -0000 From: Jerome Guitton To: gdb-patches@sourceware.org Subject: [RFA/hpux] acknowledging TTEVT_LWP_EXIT Message-ID: <20070918094806.GA1859@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="ikeVEW9yuYc//A+q" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-09/txt/msg00238.txt.bz2 --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1353 In inf-ttrace, when a TTEVT_LWP_EXIT event is received (thread exiting), the corresponding thread is removed from the thread list and never resumed. Which is wrong ; the ttrace man page reads: TTEVT_LWP_EXIT This event flag indicates that the debugger wants to be notified when a thread is exiting via the lwp_exit() system call. The thread stops upon entry to the system call. So the dying thread is stopped, it should be resumed one last time. Otherwise, any other thread waiting for its death on pthread_join would be blocked forever (e.g. in attachment, a simple program which freezes when it is run under GDB). Also in attachement, a patch that fixes this issue. It also fixes 3 unexpected failures of the testsuite on HPUX 11.11. 2007-09-18 Jerome Guitton * inf-ttrace.c (inf_ttrace_private_thread_info): New structure type. (inf_ttrace_delete_dying_threads_callback): New function. (inf_ttrace_resume): After resuming the execution, iterate over the dying threads to delete them for the thread list. (inf_ttrace_wait): on TTEVT_LWP_EXIT and TTEVT_LWP_TERMINATE, mark the corresponding thread as dying instead of removing it from the thread list. (inf_ttrace_thread_alive): return 0 for dying threads. --ikeVEW9yuYc//A+q Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="inf-ttrace.c.diff" Content-length: 3723 Index: inf-ttrace.c =================================================================== RCS file: /cvs/src/src/gdb/inf-ttrace.c,v retrieving revision 1.23 diff -u -p -r1.23 inf-ttrace.c --- inf-ttrace.c 23 Aug 2007 18:08:35 -0000 1.23 +++ inf-ttrace.c 17 Sep 2007 16:02:42 -0000 @@ -76,6 +76,11 @@ struct inf_ttrace_page_dict int count; /* Number of pages in this dictionary. */ } inf_ttrace_page_dict; +struct inf_ttrace_private_thread_info +{ + int dying; +}; + /* Number of lwps that are currently in a system call. */ static int inf_ttrace_num_lwps_in_syscall; @@ -794,6 +799,14 @@ inf_ttrace_resume_callback (struct threa return 0; } +static int +inf_ttrace_delete_dying_threads_callback (struct thread_info *info, void *arg) +{ + if (((struct inf_ttrace_private_thread_info *)info->private)->dying == 1) + delete_thread (info->ptid); + return 0; +} + static void inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal) { @@ -815,6 +828,7 @@ inf_ttrace_resume (ptid_t ptid, int step { /* Let all the other threads run too. */ iterate_over_threads (inf_ttrace_resume_callback, NULL); + iterate_over_threads (inf_ttrace_delete_dying_threads_callback, NULL); } } @@ -824,6 +838,7 @@ inf_ttrace_wait (ptid_t ptid, struct tar pid_t pid = ptid_get_pid (ptid); lwpid_t lwpid = ptid_get_lwp (ptid); ttstate_t tts; + struct thread_info *ti; /* Until proven otherwise. */ ourstatus->kind = TARGET_WAITKIND_SPURIOUS; @@ -940,19 +955,31 @@ inf_ttrace_wait (ptid_t ptid, struct tar { /* Now that we're going to be multi-threaded, add the original thread to the list first. */ - add_thread (ptid_build (tts.tts_pid, tts.tts_lwpid, 0)); + ti = add_thread (ptid_build (tts.tts_pid, tts.tts_lwpid, 0)); + ti->private = + xmalloc (sizeof (struct inf_ttrace_private_thread_info)); + memset (ti->private, 0, + sizeof (struct inf_ttrace_private_thread_info)); inf_ttrace_num_lwps++; } printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid)); - add_thread (ptid); + ti = add_thread (ptid); + ti->private = + xmalloc (sizeof (struct inf_ttrace_private_thread_info)); + memset (ti->private, 0, + sizeof (struct inf_ttrace_private_thread_info)); inf_ttrace_num_lwps++; ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0); break; case TTEVT_LWP_EXIT: printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid)); - delete_thread (ptid); + ti = find_thread_pid (ptid); + gdb_assert (ti != NULL); + ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1; inf_ttrace_num_lwps--; + ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid), + ptid_get_lwp (ptid), TT_NOPC, 0, 0); /* If we don't return -1 here, core GDB will re-add the thread. */ ptid = minus_one_ptid; break; @@ -961,7 +988,9 @@ inf_ttrace_wait (ptid_t ptid, struct tar lwpid = tts.tts_u.tts_thread.tts_target_lwpid; ptid = ptid_build (tts.tts_pid, lwpid, 0); printf_filtered(_("[%s has been terminated]\n"), target_pid_to_str (ptid)); - delete_thread (ptid); + ti = find_thread_pid (ptid); + gdb_assert (ti != NULL); + ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1; inf_ttrace_num_lwps--; ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0); break; @@ -1084,7 +1113,9 @@ inf_ttrace_files_info (struct target_ops static int inf_ttrace_thread_alive (ptid_t ptid) { - return 1; + struct thread_info *ti; + ti = find_thread_pid (ptid); + return !(((struct inf_ttrace_private_thread_info *)ti->private)->dying); } static char * --ikeVEW9yuYc//A+q Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="my_lock.c" Content-length: 373 # include static void * dummy_thread_func (void *arg) { return arg; } void glthread_in_use (void) { pthread_t thread; if (!pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0) { void *retval; if (pthread_join (thread, &retval) != 0) { abort (); } } } void main () { glthread_in_use(); } --ikeVEW9yuYc//A+q--