From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19949 invoked by alias); 16 Jun 2013 06:25:22 -0000 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 Received: (qmail 19939 invoked by uid 89); 16 Jun 2013 06:25:22 -0000 X-Spam-SWARE-Status: No, score=-6.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sun, 16 Jun 2013 06:25:20 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r5G6PJxu017099 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sun, 16 Jun 2013 02:25:19 -0400 Received: from psique (ovpn-113-133.phx2.redhat.com [10.3.113.133]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r5G6PFCi000995 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Sun, 16 Jun 2013 02:25:17 -0400 From: Sergio Durigan Junior To: GDB Patches Cc: Pedro Alves Subject: [RFC/PATCH] New convenience variable $_exitsignal X-URL: http://www.redhat.com Date: Sun, 16 Jun 2013 06:30:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2013-06/txt/msg00353.txt.bz2 This patch was proposed by Pedro at: It adds a new convenience variable called "$_exitsignal", which will hold the signal number when the inferior terminates due to the uncaught signal. I've made modifications on infrun.c:handle_inferior_event such that $_exitcode gets cleared when the inferior signalled, and vice-versa. This assumption was made because IMO the variables are mutually exclusive, i.e., when the inferior terminates because of an uncaught signal it is not possible for it to return. Anyway, Pedro's explanation seems to follow the same logic. The patch also adds a NEWS entry, documentation bits, and a testcase. OK to apply? -- Sergio gdb/ChangeLog: 2013-06-16 Sergio Durigan Junior * NEWS: Mention new convenience variable "$_exitsignal". * infrun.c (handle_inferior_event): Set internal variable "$_exitsignal" for TARGET_WAITKIND_SIGNALLED and clear "$_exitcode", vice-versa for TARGET_WAITKIND_STOPPED. gdb/testsuite/ChangeLog: 2013-06-16 Sergio Durigan Junior * gdb.base/exitsignal.exp: New file. * gdb.base/segv.c: Likewise. gdb/doc/ChangeLog: 2013-06-16 Sergio Durigan Junior * gdb.texinfo (Convenience Variables): Document "$_exitsignal". diff --git a/gdb/NEWS b/gdb/NEWS index eea9917..e9e81b3 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -69,6 +69,10 @@ show range-stepping * The exception-related catchpoints, like "catch throw", now accept a regular expression which can be used to filter exceptions by type. +* The new convenience variable $_exitsignal is automatically set to + the signal number when the program being debugged dies due to an + uncaught signal. + * MI changes ** The -trace-save MI command can optionally save trace buffer in Common diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index e6ec4ff..2025f15 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -9735,7 +9735,12 @@ to match the format in which the data was printed. @item $_exitcode @vindex $_exitcode@r{, convenience variable} The variable @code{$_exitcode} is automatically set to the exit code when -the program being debugged terminates. +the program being debugged terminates normally. + +@item $_exitsignal +@vindex $_exitsignal@r{, convenience variable} +The variable @code{$_exitsignal} is automatically set to the signal +number when the program being debugged dies due to an uncaught signal. @item $_exception The variable @code{$_exception} is set to the exception object being diff --git a/gdb/infrun.c b/gdb/infrun.c index 51a032b..f4ed1ac 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3455,6 +3455,12 @@ handle_inferior_event (struct execution_control_state *ecs) set_internalvar_integer (lookup_internalvar ("_exitcode"), (LONGEST) ecs->ws.value.integer); + /* Clear the internal variable, since if we are here chances + are the inferior has not been terminated by a signal. + And even if it has, then GDB will get to + TARGET_WAITKIND_SIGNALLED in time... */ + clear_internalvar (lookup_internalvar ("_exitsignal")); + /* Also record this in the inferior itself. */ current_inferior ()->has_exit_code = 1; current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer; @@ -3462,7 +3468,17 @@ handle_inferior_event (struct execution_control_state *ecs) print_exited_reason (ecs->ws.value.integer); } else - print_signal_exited_reason (ecs->ws.value.sig); + { + print_signal_exited_reason (ecs->ws.value.sig); + /* Set the value of the internal variable $_exitsignal, + which holds the signal uncaught by the inferior. */ + set_internalvar_integer (lookup_internalvar ("_exitsignal"), + (LONGEST) ecs->ws.value.sig); + + /* Clear the $_exitcode internal variable, because if the + inferior signalled then its return code does not exist. */ + clear_internalvar (lookup_internalvar ("_exitcode")); + } gdb_flush (gdb_stdout); target_mourn_inferior (); diff --git a/gdb/testsuite/gdb.base/exitsignal.exp b/gdb/testsuite/gdb.base/exitsignal.exp new file mode 100644 index 0000000..aa041d5 --- /dev/null +++ b/gdb/testsuite/gdb.base/exitsignal.exp @@ -0,0 +1,49 @@ +# Copyright 2013 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 segv.c + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return -1 +} + +# Run to main +if { ![runto_main] } { + return -1 +} + +# Print $_exitsignal. It should be void now, because nothing +# happened. +gdb_test "print \$_exitsignal" " = void" \ + "\$_exitsignal is void before running" + +# Trigger SIGSEGV. +gdb_test "continue" "Program received signal SIGSEGV.*" "trigger SIGSEGV" + +# Continue until the end. +gdb_test "continue" "Program terminated with signal SIGSEGV.*" \ + "program terminated with SIGSEGV" + +# Now, print $_exitsignal again. It should be 11 (SIGSEGV). +gdb_test "print \$_exitsignal" " = 11" + +# Re-run to main, i.e., restart the executable. +if { ![rerun_to_main] } { + return -1 +} + +# Print the $_exitsignal again. Even in this normal scenario, it +# should still contain the signal triggered in the other run. +gdb_test "print \$_exitsignal" " = 11" diff --git a/gdb/testsuite/gdb.base/segv.c b/gdb/testsuite/gdb.base/segv.c new file mode 100644 index 0000000..dddbd4c --- /dev/null +++ b/gdb/testsuite/gdb.base/segv.c @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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 . + +*/ + +/* This test can be used just to generate a SIGSEGV. */ + +#include + +int +main (int argc, char *argv[]) +{ + char *p = NULL; + + /* Generating a SIGSEGV. */ + *p = 1; +}