diff options
author | Pedro Alves <palves@redhat.com> | 2017-09-04 20:21:15 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-09-04 20:21:15 +0100 |
commit | 46a4882b3c7d9ec981568b8b13a3c9c39c8f8e61 (patch) | |
tree | 77ce5110d97ebc03e6aefd50bab539e4fcb037f5 /gdb/testsuite/gdb.base/nodebug.exp | |
parent | fe13dfecbf7d5a9ba3a5d9f52e33e0ddacb39bcc (diff) | |
download | gdb-46a4882b3c7d9ec981568b8b13a3c9c39c8f8e61.zip gdb-46a4882b3c7d9ec981568b8b13a3c9c39c8f8e61.tar.gz gdb-46a4882b3c7d9ec981568b8b13a3c9c39c8f8e61.tar.bz2 |
Stop assuming no-debug-info variables have type int
An earlier commit made GDB no longer assume no-debug-info functions
return int. This commit gives the same treatment to variables.
Currently, you can end misled by GDB over output like this:
(gdb) p var
$1 = -1
(gdb) p /x var
$2 = 0xffffffff
until you realize that GDB is assuming that the variable is an "int",
because:
(gdb) ptype var
type = <data variable, no debug info>
You may try to fix it by casting, but that doesn't really help:
(gdb) p /x (unsigned long long) var
$3 = 0xffffffffffffffff # incorrect
^^
That's incorrect output, because the variable was defined like this:
uint64_t var = 0x7fffffffffffffff;
^^
What happened is that with the cast, GDB did an int -> 'unsigned long
long' conversion instead of reinterpreting the variable as the cast-to
type. To get at the variable properly you have to reinterpret the
variable's address manually instead, with either:
(gdb) p /x *(unsigned long long *) &var
$4 = 0x7fffffffffffffff
(gdb) p /x {unsigned long long} &var
$5 = 0x7fffffffffffffff
After this commit GDB does it for you. This is what you'll get
instead:
(gdb) p var
'var' has unknown type; cast it to its declared type
(gdb) p /x (unsigned long long) var
$1 = 0x7fffffffffffffff
As in the functions patch, the "compile" machinery doesn't currently
have the cast-to type handy, so it continues assuming no-debug
variables have int type, though now at least it warns.
The change to gdb.cp/m-static.exp deserves an explanation:
- gdb_test "print 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
+ gdb_test "print (int) 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
That's printing the "sintvar" function local static of the
"gnu_obj_1::method()" method.
The problem with that test is that that "'S::method()::static_var'"
syntax doesn't really work in C++ as you'd expect. The way to make it
work correctly currently is to quote the method part, not the whole
expression, like:
(gdb) print 'gnu_obj_1::method()'::sintvar
If you wrap the whole expression in quotes, like in m-static.exp, what
really happens is that the parser considers the whole string as a
symbol name, but there's no debug symbol with that name. However,
local statics have linkage and are given a mangled name that demangles
to the same string as the full expression, so that's what GDB prints.
After this commit, and without the cast, the print in m-static.exp
would error out saying that the variable has unknown type:
(gdb) p 'gnu_obj_1::method()::sintvar'
'gnu_obj_1::method()::sintvar' has unknown type; cast it to its declared type
TBC, if currently (even before this series) you try to print any
function local static variable of type other than int, you'll get
bogus results. You can see that with m-static.cc as is, even.
Printing the "svar" local, which is a boolean (1 byte) still prints as
"int" (4 bytes):
(gdb) p 'gnu_obj_1::method()::svar'
$1 = 1
(gdb) ptype 'gnu_obj_1::method()::svar'
type = <data variable, no debug info>
This probably prints some random bogus value on big endian machines.
If 'svar' was of some aggregate type (etc.) we'd still print it as
int, so the problem would have been more obvious... After this
commit, you'll get instead:
(gdb) p 'gnu_obj_1::method()::svar'
'gnu_obj_1::method()::svar' has unknown type; cast it to its declared type
... so at least GDB is no longer misleading. Making GDB find the real
local static debug symbol is the subject of the following patches. In
the end, it'll all "Just Work".
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* ax-gdb.c: Include "typeprint.h".
(gen_expr_for_cast): New function.
(gen_expr) <OP_CAST, OP_CAST_TYPE>: Use it.
<OP_VAR_VALUE, OP_MSYM_VAR_VALUE>: Error out if the variable's
type is unknown.
* dwarf2read.c (new_symbol_full): Fallback to int instead of
nodebug_data_symbol.
* eval.c: Include "typeprint.h".
(evaluate_subexp_standard) <OP_VAR_VALUE, OP_VAR_MSYM_VALUE>:
Error out if symbol has unknown type.
<UNOP_CAST, UNOP_CAST_TYPE>: Common bits factored out to
evaluate_subexp_for_cast.
(evaluate_subexp_for_address, evaluate_subexp_for_sizeof): Handle
OP_VAR_MSYM_VALUE.
(evaluate_subexp_for_cast): New function.
* gdbtypes.c (init_nodebug_var_type): New function.
(objfile_type): Use it to initialize types of variables with no
debug info.
* typeprint.c (error_unknown_type): New.
* typeprint.h (error_unknown_type): New declaration.
* compile/compile-c-types.c (convert_type_basic): Handle
TYPE_CODE_ERROR; warn and fallback to int for variables with
unknown type.
gdb/testsuite/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.asm/asm-source.exp: Add casts to int.
* gdb.base/nodebug.c (dataglobal8, dataglobal32_1, dataglobal32_2)
(dataglobal64_1, dataglobal64_2): New globals.
* gdb.base/nodebug.exp: Test different expressions involving the
new globals, with print, whatis and ptype. Add casts to int.
* gdb.base/solib-display.exp: Add casts to int.
* gdb.compile/compile-ifunc.exp: Expect warning. Add cast to int.
* gdb.cp/m-static.exp: Add cast to int.
* gdb.dwarf2/dw2-skip-prologue.exp: Add cast to int.
* gdb.threads/tls-nodebug.exp: Check that gdb errors out printing
tls variable with no debug info without a cast. Test with a cast
to int too.
* gdb.trace/entry-values.exp: Add casts.
Diffstat (limited to 'gdb/testsuite/gdb.base/nodebug.exp')
-rw-r--r-- | gdb/testsuite/gdb.base/nodebug.exp | 78 |
1 files changed, 64 insertions, 14 deletions
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp index da704f1..2099456 100644 --- a/gdb/testsuite/gdb.base/nodebug.exp +++ b/gdb/testsuite/gdb.base/nodebug.exp @@ -152,11 +152,57 @@ if [runto inner] then { # we may or may not have debug info for those (depending on # whether we have debug info for the C runtime, for example). gdb_test_no_output "macro define uint8 unsigned char" - - gdb_test "p dataglobal" "= 3" - gdb_test "whatis dataglobal" \ - "<(data variable|variable), no debug info>|int" - gdb_test "ptype dataglobal" "<(data variable|variable), no debug info>|int" + gdb_test_no_output "macro define uint32 unsigned int" + gdb_test_no_output "macro define uint64 unsigned long long" + + set data_var_type "<data variable, no debug info>" + set unk_type_re "has unknown type.*to its declared type" + set ptr_math_re "Cannot perform pointer math on incomplete type \"$data_var_type\", try casting to a known type, or void \\*\\." + set not_mem_re "Attempt to take address of value not located in memory\\." + + set dataglobal_unk_re "dataglobal.*$unk_type_re" + + #exp #fmt #print #ptype/whatis + foreach line { + {"dataglobal" "" $dataglobal_unk_re " = $data_var_type"} + {"(int) dataglobal" "" "= 3" " = int"} + {"sizeof(dataglobal)" "" $dataglobal_unk_re $dataglobal_unk_re} + {"sizeof(dataglobal + 1)" "" $dataglobal_unk_re $dataglobal_unk_re} + {"sizeof((int) dataglobal)" "" " = $decimal" " = int"} + {"dataglobal + 1" "" $dataglobal_unk_re $dataglobal_unk_re} + {"&dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"} + {"&dataglobal + 1" "" $ptr_math_re $ptr_math_re} + {"(int *) &dataglobal + 1" "" " = \\(int \\*\\) $hex <datalocal>" "int \\*"} + {"&(int) dataglobal + 1" "" $not_mem_re $not_mem_re} + {"&dataglobal, &dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"} + {"*dataglobal" "" $dataglobal_unk_re $dataglobal_unk_re} + + {"dataglobal8" "/x" $dataglobal_unk_re " = $data_var_type"} + {"(uint8) dataglobal8" "/x" " = 0xff" "unsigned char"} + + {"dataglobal32_1" "/x" $dataglobal_unk_re " = $data_var_type"} + {"(uint32) dataglobal32_1" "/x" " = 0x7fffffff" "unsigned int"} + {"dataglobal32_2" "/x" $dataglobal_unk_re " = $data_var_type"} + {"(uint32) dataglobal32_2" "/x" " = 0xff" "unsigned int"} + + {"dataglobal64_1" "/x" $dataglobal_unk_re " = $data_var_type"} + {"(uint64) dataglobal64_1" "/x" " = 0x7fffffffffffffff" "unsigned long long"} + {"dataglobal64_2" "/x" $dataglobal_unk_re " = $data_var_type"} + {"(uint64) dataglobal64_2" "/x" " = 0xff" "unsigned long long"} + } { + set exp [lindex $line 0] + # Expand variables. + set fmt [subst -nobackslashes [lindex $line 1]] + set print [subst -nobackslashes [lindex $line 2]] + set whatis [subst -nobackslashes [lindex $line 3]] + if {$fmt == ""} { + gdb_test "p $exp" $print + } else { + gdb_test "p $fmt $exp" $print + } + gdb_test "whatis $exp" $whatis + gdb_test "ptype $exp" $whatis + } # The only symbol xcoff puts out for statics is for the TOC entry. # Possible, but hairy, for gdb to deal. Right now it doesn't, it @@ -164,35 +210,39 @@ if [runto inner] then { setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "p datalocal" "= 4" + gdb_test "p datalocal" "datalocal.*$unk_type_re" + gdb_test "p (int) datalocal" "= 4" setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "whatis datalocal" "<(data variable|variable), no debug info>" + gdb_test "whatis datalocal" "datalocal.*$data_var_type" setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "ptype datalocal" "<(data variable|variable), no debug info>" - gdb_test "p bssglobal" "= 0" - gdb_test "whatis bssglobal" "<(data variable|variable), no debug info>|int" - gdb_test "ptype bssglobal" "<(data variable|variable), no debug info>|int" + gdb_test "ptype datalocal" "datalocal.*$data_var_type" + + gdb_test "p bssglobal" "bssglobal.*$unk_type_re" + gdb_test "p (int) bssglobal" "= 0" + gdb_test "whatis bssglobal" $data_var_type + gdb_test "ptype bssglobal" $data_var_type setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "p bsslocal" "= 0" + gdb_test "p bsslocal" "bsslocal.*$unk_type_re" + gdb_test "p (int) bsslocal" "= 0" setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "whatis bsslocal" "<(data variable|variable), no debug info>" + gdb_test "whatis bsslocal" $data_var_type setup_xfail "rs6000*-*-aix*" setup_xfail "powerpc*-*-aix*" - gdb_test "ptype bsslocal" "<(data variable|variable), no debug info>" + gdb_test "ptype bsslocal" $data_var_type gdb_test "backtrace 10" "#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \ "backtrace from inner in nodebug.exp" |