diff options
author | Nils-Christian Kempke <nils-christian.kempke@intel.com> | 2022-08-04 08:52:28 +0200 |
---|---|---|
committer | Nils-Christian Kempke <nils-christian.kempke@intel.com> | 2022-08-31 10:28:27 +0200 |
commit | 244a9a81010130aa250171db55fb137b2fd581d9 (patch) | |
tree | 3d908cf7e741d64a502db6cf0fc3a13fae244b7f | |
parent | 803584b96d97e1f6ea50b0a0064d2a03ab0baa60 (diff) | |
download | fsf-binutils-gdb-244a9a81010130aa250171db55fb137b2fd581d9.zip fsf-binutils-gdb-244a9a81010130aa250171db55fb137b2fd581d9.tar.gz fsf-binutils-gdb-244a9a81010130aa250171db55fb137b2fd581d9.tar.bz2 |
gdb, testsuite: adapt function_range expected name
When writing a dwarf testcase for some C++ code I wanted to use the
MACRO_AT_range which in turn uses the function_range proc in dwarf.exp
to extract the bounds of 'main'.
However, the macro failed as GDB prints the C++ 'main' with its
arguments as 'main(int, char**)' or 'main()'.
The reason for this is that in read.c::dwarf2_compute_name we call
c_type_print_args on C++ functions and append their arguments to the
function name. This happens to all C++ functions, but is only visible
when the function doesn't have a linkage name.
An example might make this more clear. Given the following code
>> cat c.cpp
int foo (int a, float b)
{
return 0;
}
int main (int argc, char **argv)
{
return 0;
}
which is legal in both languages, C and C++, and compiling it with
e.g. clang or gcc will make the disassemble command look like:
>> clang --version
clang version 10.0.0-4ubuntu1
...
>> clang -O0 -g ./c.cpp
>> gdb -q ./a.out -ex "start"
...
(gdb) disassemble main
Dump of assembler code for function main(int, char**):
0x0000000000401120 <+0>: push %rbp
0x0000000000401121 <+1>: mov %rsp,%rbp
...
0x0000000000401135 <+21>: ret
End of assembler dump.
(gdb) disassemble foo
Dump of assembler code for function _Z3fooif:
0x0000000000401110 <+0>: push %rbp
0x0000000000401111 <+1>: mov %rsp,%rbp
...
0x000000000040111f <+15>: ret
End of assembler dump.
Note, that main is emitted with its arguments while for foo the linkage
name is being printed, as also visible in its DWARF:
>> objdump ./a.out --dwarf=info | grep "foo" -A3 -B3
<2b> DW_AT_low_pc : 0x401110
<33> DW_AT_high_pc : 0x10
<37> DW_AT_frame_base : 1 byte block: 56 (DW_OP_reg6 (rbp))
<39> DW_AT_linkage_name: (indirect string, offset: 0x39): _Z3fooif
<3d> DW_AT_name : (indirect string, offset: 0x42): foo
<41> DW_AT_decl_file : 1
<42> DW_AT_decl_line : 1
<43> DW_AT_type : <0x9a>
Now, let's rename the C++ file and compile it as C:
>> mv c.cpp c.c
>> clang -O0 -g ./c.c
>> gdb -q ./a.out -ex "start'
...
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000401120 <+0>: push %rbp
0x0000000000401121 <+1>: mov %rsp,%rbp
...
0x0000000000401135 <+21>: ret
End of assembler dump.
(gdb) disassemble foo
Dump of assembler code for function foo:
0x0000000000401110 <+0>: push %rbp
0x0000000000401111 <+1>: mov %rsp,%rbp
...
0x000000000040111f <+15>: ret
End of assembler dump.
Note, for foo we did not get a linkage name emitted in DWARF, so
it is printed by its name:
>> objdump --dwarf=info ./a.out | grep foo -A3 -B3
<2b> DW_AT_low_pc : 0x401110
<33> DW_AT_high_pc : 0x10
<37> DW_AT_frame_base : 1 byte block: 56 (DW_OP_reg6 (rbp))
<39> DW_AT_name : (indirect string, offset: 0x37): foo
<3d> DW_AT_decl_file : 1
<3e> DW_AT_decl_line : 1
<3f> DW_AT_prototyped : 1
To make the macro and proc work with C++ as well, an optional argument
list was added to the regex matching the function name in the
disassemble command in function_range. This does not change any used
behavior as currently, there exists no C++ test using the proc
function_range.
Signed-off-by: Nils-Christian Kempke <nils-christian.kempke@intel.com>
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 3d833e5..b5474ca 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -391,10 +391,14 @@ proc function_range { func src {options {debug}} } { } # Compute the size of the last instruction. - if { $func_length == 0 } then { - set func_pattern "$func" - } else { - set func_pattern "$func\\+$func_length" + # For C++, GDB appends arguments to the names of functions if they don't + # have a linkage name. For example, asking gdb to disassemble a C++ main + # will print the function name as main() or main(int argc, char **argv). + # Take this into account by optionally allowing an argument list after + # the function name. + set func_pattern "$func\(\?\:\\(\.\*\\)\)?" + if { $func_length != 0 } { + set func_pattern "$func_pattern\\+$func_length" } set test "x/2i $func+$func_length" gdb_test_multiple $test $test { |