From: Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org>
To: Nils-Christian Kempke <nils-christian.kempke@intel.com>,
gdb-patches@sourceware.org
Subject: Re: [PATCH v2 1/2] gdb, testsuite: adapt function_range expected name
Date: Wed, 10 Aug 2022 14:31:56 +0200 [thread overview]
Message-ID: <3d9918c1-52f6-5d0e-c57f-5cf27b2e8cc0@redhat.com> (raw)
In-Reply-To: <20220804130351.3898972-2-nils-christian.kempke@intel.com>
On 04/08/2022 15:03, Nils-Christian Kempke wrote:
> 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 does not only happen for 'main' but also for all
> other C++ functions. However, other functions often also have a
> DW_AT_linkage_name which gets printed over the function name in
> 'disassemble' and similar functions. So, I could only really reproduce
> the fail of MARCRO_AT_rang with the C++ 'main' function.
Hi Nils, thank you for working on this!
I found this explanation a bit confusing, maybe you could condense it to
something like
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
it 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>
> ---
> 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 356451bcaac..2c1c4056346 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. These names
> + # will (if no linkage name is present, and, e.g., main generally has none)
> + # make 'dissasemble' print main (and possibly others) as 'main()' or
> + # 'main(int argc, char **argv)' so we take this into accound here by
> + # allowing an optinal argument list after the function name.
I also think the explanation here could be improved a bit. Maybe
something like:
# For C++, GDB appends arguments to the names of functions if they don't
have
# a linkage name. For example, asking gdb to disassemble 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.
The code itself LGTM, however I can't approve patches for pushing.
--
Cheers,
Bruno
> + 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 {
next prev parent reply other threads:[~2022-08-10 12:32 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-04 13:03 Nils-Christian Kempke via Gdb-patches
2022-08-04 13:03 ` [PATCH v2 2/2] gdb, dwarf: create symbols for template tags without names Nils-Christian Kempke via Gdb-patches
2022-08-10 12:49 ` Bruno Larsen via Gdb-patches
2022-08-10 12:31 ` Bruno Larsen via Gdb-patches [this message]
2022-08-23 15:35 ` [PATCH v2 1/2] gdb, testsuite: adapt function_range expected name Kempke, Nils-Christian via Gdb-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3d9918c1-52f6-5d0e-c57f-5cf27b2e8cc0@redhat.com \
--to=gdb-patches@sourceware.org \
--cc=blarsen@redhat.com \
--cc=nils-christian.kempke@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox