From: Sergio Durigan Junior Date: Mon, 9 Mar 2020 22:47:47 +0000 (-0400) Subject: Fix printf of a convenience variable holding an inferior address X-Git-Tag: gdb-9.2-release~75 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=141e490226a99e0359393ddaca5628c68de036dc;p=thirdparty%2Fbinutils-gdb.git Fix printf of a convenience variable holding an inferior address Back at: commit 1f6f6e21fa86dc3411a6498608f32e9eb24b7851 Author: Philippe Waroquiers 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 PR gdb/25650 * 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 PR gdb/25650 * gdb.base/printcmds.exp: Add test to verify printf of a variable holding an address. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d642165c59a..d67864511ba 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2020-03-03 Sergio Durigan Junior + + PR gdb/25650 + * printcmd.c (print_c_string): Check also for TYPE_CODE_PTR + when verifying if dealing with a convenience variable. + 2020-02-22 Eli Zaretskii PRE gdb/25586: diff --git a/gdb/printcmd.c b/gdb/printcmd.c index ed2c8d47add..0df9826888a 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 ec507fd1b21..90e26950c4e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-03-03 Sergio Durigan Junior + + PR gdb/25650 + * gdb.base/printcmds.exp: Add test to verify printf of a + variable holding an address. + 2020-02-07 Tom Tromey PR breakpoints/24915: diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp index 6e98b7943ba..f1816e637b2 100644 --- a/gdb/testsuite/gdb.base/printcmds.exp +++ b/gdb/testsuite/gdb.base/printcmds.exp @@ -1025,6 +1025,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