From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6808 invoked by alias); 13 Sep 2013 21:17:14 -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 6795 invoked by uid 89); 13 Sep 2013 21:17:13 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Sep 2013 21:17:13 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.0 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8DLH88n030458 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Sep 2013 17:17:08 -0400 Received: from psique (ovpn-113-70.phx2.redhat.com [10.3.113.70]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r8DLH4G4019607 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Fri, 13 Sep 2013 17:17:06 -0400 From: Sergio Durigan Junior To: Eli Zaretskii Cc: dje@google.com, gdb-patches@sourceware.org Subject: Re: [PATCH/RFA] Introduce new $_isvoid() convenience function References: <83a9jhi3h0.fsf@gnu.org> <83li30h5z0.fsf@gnu.org> <83ioy4h5cl.fsf@gnu.org> X-URL: http://www.redhat.com Date: Fri, 13 Sep 2013 21:17:00 -0000 In-Reply-To: <83ioy4h5cl.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 13 Sep 2013 22:46:50 +0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2013-09/txt/msg00409.txt.bz2 On Friday, September 13 2013, Eli Zaretskii wrote: >> From: Sergio Durigan Junior >> Cc: dje@google.com, gdb-patches@sourceware.org >> Date: Fri, 13 Sep 2013 16:40:52 -0300 >> >> > This is fine, but I would also include an example with $_exitcode. >> >> I intend to expand this explanation when I resubmit the patch for >> $_exitsignal. In fact, I will add another example showing the behavior >> of $_exitsignal and $_exitcode. But if you wish, I can add $_exitcode >> here as well. > > It would be best to have the explanation in both places, or at least a > cross-reference from one to the other. WDYT of this version? -- Sergio diff --git a/gdb/NEWS b/gdb/NEWS index ad97f6f..13bb647 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,14 @@ *** Changes since GDB 7.6 +* New convenience function "$_isvoid", to check whether an expression + is void. A void expression is an expression where the type of the + result is "void". For example, some convenience variables may be + "void" when evaluated (e.g., "$_exitcode" before the execution of + the program being debugged; or an undefined convenience variable). + Another example, when calling a function whose return type is + "void". + * The "maintenance print objfiles" command now takes an optional regexp. * The "catch syscall" command now works on arm*-linux* targets. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b6ba239..33318b8 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -9800,6 +9800,69 @@ function can be used in an expression just like an ordinary function; however, a convenience function is implemented internally to @value{GDBN}. +These functions do not require @value{GDBN} to be configured with +@code{Python} support, which means that they are always available. + +@table @code + +@item $_isvoid (@var{expr}) +@findex $_isvoid@r{, convenience function} +Return one if the expression @var{expr} is @code{void}. Otherwise it +returns zero. + +A @code{void} expression is an expression where the type of the result +is @code{void}. For example, you can examine a convenience variable +(see @ref{Convenience Vars,, Convenience Variables}) to check whether +it is @code{void}: + +@smallexample +(@value{GDBP}) print $_exitcode +$1 = void +(@value{GDBP}) print $_isvoid ($_exitcode) +$2 = 1 +(@value{GDBP}) run +Starting program: ./a.out +[Inferior 1 (process 29572) exited normally] +(@value{GDBP}) print $_exitcode +$3 = 0 +(@value{GDBP}) print $_isvoid ($_exitcode) +$4 = 0 +@end smallexample + +In the example above, we used @code{$_isvoid} to check whether +@code{$_exitcode} is @code{void} before and after the execution of the +program being debugged. Before the execution there is no exit code to +be examined, therefore @code{$_exitcode} is @code{void}. After the +execution the program being debugged returned zero, therefore +@code{$_exitcode} is zero, which means that it is not @code{void} +anymore. + +The @code{void} expression can also be a call of a function from the +program being debugged. For example, given the following function: + +@smallexample +void +foo (void) +@{ +@} +@end smallexample + +The result of calling it inside @value{GDBN} is @code{void}: + +@smallexample +(@value{GDBP}) print foo () +$1 = void +(@value{GDBP}) print $_isvoid (foo ()) +$2 = 1 +(@value{GDBP}) set $v = foo () +(@value{GDBP}) print $v +$3 = void +(@value{GDBP}) print $_isvoid ($v) +$4 = 1 +@end smallexample + +@end table + These functions require @value{GDBN} to be configured with @code{Python} support. diff --git a/gdb/testsuite/gdb.base/gdbvars.c b/gdb/testsuite/gdb.base/gdbvars.c index aa3b4d8..352a76b 100644 --- a/gdb/testsuite/gdb.base/gdbvars.c +++ b/gdb/testsuite/gdb.base/gdbvars.c @@ -4,6 +4,17 @@ typedef void *ptr; ptr p = &p; +static void +foo_void (void) +{ +} + +static int +foo_int (void) +{ + return 0; +} + int main () { diff --git a/gdb/testsuite/gdb.base/gdbvars.exp b/gdb/testsuite/gdb.base/gdbvars.exp index 23a6758..85aaca0 100644 --- a/gdb/testsuite/gdb.base/gdbvars.exp +++ b/gdb/testsuite/gdb.base/gdbvars.exp @@ -54,6 +54,34 @@ proc test_convenience_variables {} { "Print contents of uninitialized convenience variable" } +proc test_convenience_functions {} { + gdb_test "print \$_isvoid" " = " \ + "Print internal function \$_isvoid" + + gdb_test "print \$isvoid_foo" " = void" \ + "Print void convenience variable" + + gdb_test "print \$_isvoid (\$isvoid_foo)" " = 1" \ + "Check whether void convenience variable is void" + + gdb_test_no_output "set \$isvoid_foo = 1" \ + "Set void convenience variable to 1" + + gdb_test "print \$_isvoid (\$isvoid_foo)" " = 0" \ + "Check whether non-void convenience variable is void" + + # For the next test, we need the inferior to be running. + if { ![runto_main] } { + return -1 + } + + gdb_test "print \$_isvoid (foo_void ())" " = 1" \ + "Check whether void function is void" + + gdb_test "print \$_isvoid (foo_int ())" " = 0" \ + "Check whether non-void function is void" +} + proc test_value_history {} { global gdb_prompt @@ -114,4 +142,5 @@ gdb_test_no_output "set print sevenbit-strings" test_value_history test_convenience_variables +test_convenience_functions test_with_program diff --git a/gdb/value.c b/gdb/value.c index 42a8d2f..edbfc70 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3584,6 +3584,23 @@ value_fetch_lazy (struct value *val) return 0; } +/* Implementation of the convenience function $_isvoid. */ + +static struct value * +isvoid_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, struct value **argv) +{ + int ret; + + if (argc != 1) + error (_("You must provide one parameter for $_isvoid.")); + + ret = TYPE_CODE (value_type (argv[0])) == TYPE_CODE_VOID; + + return value_from_longest (builtin_type (gdbarch)->builtin_int, ret); +} + void _initialize_values (void) { @@ -3616,4 +3633,10 @@ VARIABLE is already initialized.")); add_prefix_cmd ("function", no_class, function_command, _("\ Placeholder command for showing help on convenience functions."), &functionlist, "function ", 0, &cmdlist); + + add_internal_function ("_isvoid", _("\ +Check whether an expression is void.\n\ +Usage: $_isvoid (expression)\n\ +Return 1 if the expression is void, zero otherwise."), + isvoid_internal_fn, NULL); }