This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH/RFA] Introduce new $_isvoid() convenience function
- From: Sergio Durigan Junior <sergiodj at redhat dot com>
- To: Eli Zaretskii <eliz at gnu dot org>
- Cc: dje at google dot com, gdb-patches at sourceware dot org
- Date: Fri, 13 Sep 2013 18:17:03 -0300
- Subject: Re: [PATCH/RFA] Introduce new $_isvoid() convenience function
- Authentication-results: sourceware.org; auth=none
- References: <m3a9jh6bs0 dot fsf at redhat dot com> <CADPb22Q-66NK8u3DLTSG0K7QSYNaxVa0SRBQoBCXoLy7OHvZ9w at mail dot gmail dot com> <m3txhp2pes dot fsf at redhat dot com> <83a9jhi3h0 dot fsf at gnu dot org> <m31u4s39be dot fsf at redhat dot com> <83li30h5z0 dot fsf at gnu dot org> <m3ioy4y0fv dot fsf at redhat dot com> <83ioy4h5cl dot fsf at gnu dot org>
On Friday, September 13 2013, Eli Zaretskii wrote:
>> From: Sergio Durigan Junior <sergiodj@redhat.com>
>> 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" " = <internal function _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);
}