From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7876) id A897E383CCEE; Wed, 31 Aug 2022 08:29:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A897E383CCEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1661934564; bh=CQ06fg2UT6heMi1FkmnPy6BkKr5SY7ehydsHHRUUJMI=; h=From:To:Subject:Date:From; b=l58enlBxfjZ0T4vXKCnKGpki7F+Wm0uAH8qXTU8x11ag9kQijqQ7O4pI2khXYdvWv Uy9uyOLRUwfCWSkIXIOyIrmhRTtAQlx67DvCxsglzPk5sfVnf1I1uPKTdXw88g7l6g 8bL4bw4kPxrSqVzqM0MMRQ7NlWNaXzfc4VzJZt3w= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Nils-Christian Kempke To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb, testsuite: adapt function_range expected name X-Act-Checkin: binutils-gdb X-Git-Author: Nils-Christian Kempke X-Git-Refname: refs/heads/master X-Git-Oldrev: 803584b96d97e1f6ea50b0a0064d2a03ab0baa60 X-Git-Newrev: 244a9a81010130aa250171db55fb137b2fd581d9 Message-Id: <20220831082924.A897E383CCEE@sourceware.org> Date: Wed, 31 Aug 2022 08:29:24 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D244a9a810101= 30aa250171db55fb137b2fd581d9 commit 244a9a81010130aa250171db55fb137b2fd581d9 Author: Nils-Christian Kempke Date: Thu Aug 4 08:52:28 2022 +0200 gdb, testsuite: adapt function_range expected name =20 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'. =20 However, the macro failed as GDB prints the C++ 'main' with its arguments as 'main(int, char**)' or 'main()'. =20 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. =20 An example might make this more clear. Given the following code =20 >> cat c.cpp int foo (int a, float b) { return 0; } =20 int main (int argc, char **argv) { return 0; } =20 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: =20 >> 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. =20 Note, that main is emitted with its arguments while for foo the linkage name is being printed, as also visible in its DWARF: =20 >> objdump ./a.out --dwarf=3Dinfo | 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): _Z3fo= oif <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> =20 Now, let's rename the C++ file and compile it as C: =20 >> 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. =20 Note, for foo we did not get a linkage name emitted in DWARF, so it is printed by its name: =20 >> objdump --dwarf=3Dinfo ./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 =20 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. =20 Signed-off-by: Nils-Christian Kempke Diff: --- gdb/testsuite/lib/dwarf.exp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 3d833e5cd58..b5474ca6ce4 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -391,10 +391,14 @@ proc function_range { func src {options {debug}} } { } =20 # Compute the size of the last instruction. - if { $func_length =3D=3D 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++ m= ain + # 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 !=3D 0 } { + set func_pattern "$func_pattern\\+$func_length" } set test "x/2i $func+$func_length" gdb_test_multiple $test $test {