From patchwork Thu Aug 21 18:45:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 2510 Received: (qmail 22521 invoked by alias); 21 Aug 2014 18:45:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 22511 invoked by uid 89); 21 Aug 2014 18:45:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 21 Aug 2014 18:45:07 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s7LIj5jE016813 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 21 Aug 2014 14:45:06 -0400 Received: from host2.jankratochvil.net (ovpn-116-19.ams2.redhat.com [10.36.116.19]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7LIj1GI001344 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 21 Aug 2014 14:45:04 -0400 Date: Thu, 21 Aug 2014 20:45:01 +0200 From: Jan Kratochvil To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: [commit+7.8] [patch+7.8?] Fix 'gcore' with exited threads Message-ID: <20140821184501.GA19138@host2.jankratochvil.net> References: <20140609203020.GA22447@host2.jankratochvil.net> <53A8427D.6070902@redhat.com> <20140817211647.GA17152@host2.jankratochvil.net> <53F5D8E9.5050900@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <53F5D8E9.5050900@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes On Thu, 21 Aug 2014 13:32:57 +0200, Pedro Alves wrote: > On 08/17/2014 10:16 PM, Jan Kratochvil wrote: > > On Mon, 23 Jun 2014 17:06:37 +0200, Pedro Alves wrote: > >> > What does the log show ? > > gcore .../gdb/testsuite/gdb.threads/gcore-thread0.test^M > > Cannot find new threads: debugger service failed^M > > (gdb) FAIL: gdb.threads/gcore-thread.exp: save a zeroed-threads corefile > > + > > core .../gdb/testsuite/gdb.threads/gcore-thread0.test^M > > ".../gdb/testsuite/gdb.threads/gcore-thread0.test" is not a core dump: File format not recognized^M > > (gdb) FAIL: gdb.threads/gcore-thread.exp: core0file: re-load generated corefile (bad file format) > > Thanks. It'd be good to have this in the commit log. I have put it to the commit log. For the record as discussed in the past and not to repeat myself I just do not agree with this statement. > Otherwise OK. Checked in: 22fd09ae995556cc1b898afe3d5901eb161d1102 > IMO, this is good for 7.8. Checked in: 14adc931130880d75eccc023cbaec68790960235 Thanks, Jan commit 22fd09ae995556cc1b898afe3d5901eb161d1102 Author: Jan Kratochvil Date: Thu Aug 21 20:36:20 2014 +0200 Fix 'gcore' with exited threads Program received signal SIGABRT, Aborted. [...] (gdb) gcore foobar Couldn't get registers: No such process. (gdb) info threads [...] (gdb) gcore foobar Saved corefile foobar (gdb) gcore tries to access the exited thread: [Thread 0x7ffff7fce700 (LWP 6895) exited] ptrace(PTRACE_GETREGS, 6895, 0, 0x7fff18167dd0) = -1 ESRCH (No such process) Without the TRY_CATCH protection testsuite FAILs for: gcore .../gdb/testsuite/gdb.threads/gcore-thread0.test Cannot find new threads: debugger service failed (gdb) FAIL: gdb.threads/gcore-thread.exp: save a zeroed-threads corefile + core .../gdb/testsuite/gdb.threads/gcore-thread0.test ".../gdb/testsuite/gdb.threads/gcore-thread0.test" is not a core dump: File format not recognized (gdb) FAIL: gdb.threads/gcore-thread.exp: core0file: re-load generated corefile (bad file format) Maybe the TRY_CATCH could be more inside update_thread_list(). Similar update_thread_list() call is IMO missing in procfs_make_note_section() but I do not have where to verify that change. gdb/ChangeLog 2014-08-21 Jan Kratochvil * linux-tdep.c (linux_corefile_thread_callback): Ignore THREAD_EXITED. (linux_make_corefile_notes): call update_thread_list, protected against exceptions. gdb/testsuite/ChangeLog 2014-08-21 Jan Kratochvil * gdb.threads/gcore-stale-thread.c: New file. * gdb.threads/gcore-stale-thread.exp: New file. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bf7f618..e8f652f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2014-08-21 Jan Kratochvil + + * linux-tdep.c (linux_corefile_thread_callback): Ignore THREAD_EXITED. + (linux_make_corefile_notes): call update_thread_list, protected against + exceptions. + 2014-08-21 Pedro Alves * infcmd.c (attach_command): Remove comment. diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index d0f1106..dae59c5 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1194,6 +1194,11 @@ linux_corefile_thread_callback (struct thread_info *info, void *data) { struct linux_corefile_thread_data *args = data; + /* It can be current thread + which cannot be removed by update_thread_list. */ + if (info->state == THREAD_EXITED) + return 0; + if (ptid_get_pid (info->ptid) == args->pid) { struct cleanup *old_chain; @@ -1445,6 +1450,7 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size, char *note_data = NULL; gdb_byte *auxv; int auxv_len; + volatile struct gdb_exception e; if (linux_fill_prpsinfo (&prpsinfo)) { @@ -1468,6 +1474,12 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size, } /* Thread register information. */ + TRY_CATCH (e, RETURN_MASK_ERROR) + { + update_thread_list (); + } + if (e.reason < 0) + exception_print (gdb_stderr, e); thread_args.gdbarch = gdbarch; thread_args.pid = ptid_get_pid (inferior_ptid); thread_args.obfd = obfd; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 31c64ff..8689b5e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-08-21 Jan Kratochvil + + * gdb.threads/gcore-stale-thread.c: New file. + * gdb.threads/gcore-stale-thread.exp: New file. + 2014-08-21 Pedro Alves * gdb.base/gcore-buffer-overflow.exp: Remove "help gcore" test. diff --git a/gdb/testsuite/gdb.threads/gcore-stale-thread.c b/gdb/testsuite/gdb.threads/gcore-stale-thread.c new file mode 100644 index 0000000..944acba --- /dev/null +++ b/gdb/testsuite/gdb.threads/gcore-stale-thread.c @@ -0,0 +1,48 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include + +static pthread_t main_thread; + +static void * +start (void *arg) +{ + int i; + + i = pthread_join (main_thread, NULL); + assert (i == 0); + + return arg; /* break-here */ +} + +int +main (void) +{ + pthread_t thread; + int i; + + main_thread = pthread_self (); + + i = pthread_create (&thread, NULL, start, NULL); + assert (i == 0); + + pthread_exit (NULL); + assert (0); + return 0; +} diff --git a/gdb/testsuite/gdb.threads/gcore-stale-thread.exp b/gdb/testsuite/gdb.threads/gcore-stale-thread.exp new file mode 100644 index 0000000..291c56f --- /dev/null +++ b/gdb/testsuite/gdb.threads/gcore-stale-thread.exp @@ -0,0 +1,57 @@ +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +standard_testfile +set corefile [standard_output_file ${testfile}.core] + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != ""} { + return -1 +} + +clean_restart ${testfile} + +gdb_test_no_output "set non-stop on" + +if { ! [ runto_main ] } then { + return -1 +} + +gdb_test_multiple "info threads" "threads are supported" { + -re ".* main .*\r\n$gdb_prompt $" { + # OK, threads are supported. + } + -re "\r\n$gdb_prompt $" { + unsupported "gdb does not support threads on this target" + return -1 + } +} + +gdb_breakpoint ${srcfile}:[gdb_get_line_number "break-here"] +# gdb_continue_to_breakpoint does not work as it uses "$gdb_prompt $" regex +# which does not work due to the output: (gdb) [Thread ... exited] +set name "continue to breakpoint: break-here" +gdb_test_multiple "continue" $name { + -re "Breakpoint .* (at|in) .* break-here .*\r\n$gdb_prompt " { + pass $name + } +} + +gdb_gcore_cmd "$corefile" "save a corefile" + +# Do not run "info threads" before "gcore" as it could workaround the bug +# by discarding non-current exited threads. +gdb_test "info threads" \ + {The current thread has terminated\. See `help thread'\.} \ + "exited thread is current due to non-stop"