This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH/RFA] Introduce new $_isvoid() convenience function


On Thursday, September 12 2013, Doug Evans wrote:

> Hi.  Thanks for persevering!

Thank you for reviewing :-).

> While I often follow "it's easier to relax restrictions than impose
> them after the fact",
> in this case I wonder if there's any reason to restrict $_isvoid() to
> convenience variables.
>
> Thoughts?
>
> For "void foo(){}", is there any real difference to:
> (gdb) set $foo = foo()
> (gdb) p $_isvoid($foo)
> (gdb) p $_isvoid(foo())
>
> [Haven't tried it, but I'm guessing removing the internalva4 check in
> your patch would make that work.]

Yes, I agree.  I have changed the code to accept not only convenience
variables, but other kinds of expressions (it was just a matter of
removing the check for internalvar, really).  BTW, I have reworded the
help message and the documentation and did s/convenience
variable/expression/g.

> Also, you've put  a fair bit of time into this, and I'm happy with
> what you've got.  And thanks!
> The high order bit here for me is being able to script $_exitcode + $exitsignal.
> If we're going with checking for a void value, one could just leave it
> to be handled in Python.

Yeah, I thought about it too, but then I thought that maybe we shouldn't
always depend on Python.  This was easy to do in C, and has the
advantage that it will be available everywhere.  But I guess you said
something along those lines below...

> OTOH, this patch is really simple, and IMO it is *nice* to be able to
> do this from just a plain gdb script,
> so I'm advocating accepting this patch (modulo maybe handling any void
> value, not just conv vars).

Nice.  I hope you like the new version of the patch.

> btw, I noticed that if I run a program to exit, and then rerun to
> main, $_exitcode has the last exit code - I would have expected it to
> get reset to void upon rerun.  After all, if I stop at main the first
> time through, $_exitcode is void.
> [I'll file a bug, no need to address this in your patch series.]

Yes, this is a bug indeed.  Thanks for filing it.  I may even have a fix
hanging around, will look.

-- 
Sergio

gdb/
2013-09-13  Sergio Durigan Junior  <sergiodj@redhat.com>

	* NEWS: Mention new convenience function $_isvoid.
	* value.c (isvoid_internal_fn): New function.
	(_initialize_values): Add new convenience function $_isvoid.

gdb/doc/
2013-09-13  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.texinfo (Convenience Functions): Mention new convenience
	function $_isvoid.

gdb/testsuite/
2013-09-13  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.base/gdbvars.c (foo_void): New function.
	(foo_int): Likewise.
	* gdb.base/gdbvars.exp (test_convenience_functions): New
	function.  Call it.

diff --git a/gdb/NEWS b/gdb/NEWS
index ad97f6f..e58d6ce 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,9 @@
 
 *** Changes since GDB 7.6
 
+* New convenience function "$_isvoid", to check whether an expression
+  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..70d580f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -9829,6 +9829,18 @@ Returns the length of string @var{str}.
 
 @end table
 
+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 @code{expr} is void.  Otherwise it
+returns zero.
+
+@end table
+
 @value{GDBN} provides the ability to list and get help on
 convenience functions.
 
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);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]