public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Fix printf of a convenience variable holding an inferior address
@ 2020-03-03 16:28 Sergio Durigan Junior
  0 siblings, 0 replies; only message in thread
From: Sergio Durigan Junior @ 2020-03-03 16:28 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7b973adce2b486518d3150db257b179e1b9a5d33

commit 7b973adce2b486518d3150db257b179e1b9a5d33
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Sun Mar 1 18:15:53 2020 -0500

    Fix printf of a convenience variable holding an inferior address
    
    Back at:
    
    commit 1f6f6e21fa86dc3411a6498608f32e9eb24b7851
    Author: Philippe Waroquiers <philippe.waroquiers@skynet.be>
    Date:   Mon Jun 10 21:41:51 2019 +0200
    
        Ensure GDB printf command can print convenience var strings without a target.
    
    GDB was extended in order to allow the printing of convenience
    variables that are strings without a target.  However, this introduced
    a regression that hasn't been caught by our testsuite (because there
    were no tests for it).
    
    The problem happens when we try to print a convenience variable that
    holds the address of a string in the inferior.  The following
    two-liners can reproduce the issue:
    
    $ echo -e 'int main(){const char a[]="test";return 0;}' | gcc -x c - -O0-g3
    $ ./gdb/gdb --data-directory ./gdb/data-directory -q ./a.out -ex 'start' -ex 'set $x = (const char *) (&a[0] + 2)' -ex 'printf "%s\n", $x'
    
    After some investigation, I found that the problem happens on
    printcmd.c:printf_c_string.  In the case above, we're taking the first
    branch of the 'if' condition, which assumes that there will be a value
    to be printed at "value_contents (value)".  There isn't.  We actually
    need to obtain the address that the variable points to, and read the
    contents from memory.
    
    It seems to me that we should avoid this branch if the TYPE_CODE of
    "value_type (value)" is TYPE_CODE_PTR (i.e., a pointer to the
    inferior's memory).  This is what this patch does.
    
    I took the liberty to extend the current testcase under
    gdb.base/printcmds.exp and create a test that exercises this scenario.
    
    No regressions have been found on Buildbot.
    
    gdb/ChangeLog:
    2020-03-03  Sergio Durigan Junior  <sergiodj@redhat.com>
    
    	* printcmd.c (print_c_string): Check also for TYPE_CODE_PTR
    	when verifying if dealing with a convenience variable.
    
    gdb/testsuite/ChangeLog:
    2020-03-03  Sergio Durigan Junior  <sergiodj@redhat.com>
    
    	* gdb.base/printcmds.exp: Add test to verify printf of a
    	variable holding an address.

Diff:
---
 gdb/ChangeLog                        | 5 +++++
 gdb/printcmd.c                       | 3 ++-
 gdb/testsuite/ChangeLog              | 5 +++++
 gdb/testsuite/gdb.base/printcmds.exp | 8 ++++++++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2400982..291e83a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2020-03-03  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+	* printcmd.c (print_c_string): Check also for TYPE_CODE_PTR
+	when verifying if dealing with a convenience variable.
+
 2020-03-03  Luis Machado  <luis.machado@linaro.org>
 
 	* auxv.c (default_print_auxv_entry): Add new AUXV entries.
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 7970414..78d8d3d 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -2260,7 +2260,8 @@ printf_c_string (struct ui_file *stream, const char *format,
 {
   const gdb_byte *str;
 
-  if (VALUE_LVAL (value) == lval_internalvar
+  if (TYPE_CODE (value_type (value)) != TYPE_CODE_PTR
+      && VALUE_LVAL (value) == lval_internalvar
       && c_is_string_type_p (value_type (value)))
     {
       size_t len = TYPE_LENGTH (value_type (value));
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 0563fec..28726b8 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-03-03  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+	* gdb.base/printcmds.exp: Add test to verify printf of a
+	variable holding an address.
+
 2020-03-03  Tom de Vries  <tdevries@suse.de>
 
 	* gdb.mi/gdb2549.exp: Fix "register values t" check-read1 timeout.
diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp
index bd2afc8..c87a151 100644
--- a/gdb/testsuite/gdb.base/printcmds.exp
+++ b/gdb/testsuite/gdb.base/printcmds.exp
@@ -1039,6 +1039,14 @@ gdb_test_no_output "set may-call-functions off"
 test_printf_convenience_var "with target, may-call-functions off"
 gdb_test_no_output "set may-call-functions on"
 
+# Test printf of a variable that holds the address to a substring in
+# the inferior.  This test will not work without a target.
+gdb_test_no_output "set var \$test_substr = \(char \*\) \(&teststring\[0\] + 4\)" \
+    "set \$test_substr var"
+gdb_test "printf \"test_substr val = %s\\n\", \$test_substr" \
+    "test_substr val = string contents" \
+    "print \$test_substr"
+
 test_integer_literals_accepted
 test_integer_literals_rejected
 test_float_accepted


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-03 16:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03 16:28 [binutils-gdb] Fix printf of a convenience variable holding an inferior address Sergio Durigan Junior

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).