c++gdbname-mangling

Why can't GDB find some functions to disassemble by name?


Sometimes there is a function in my binary that I'm sure hasn't been optimized away, because it's called by another function:

(gdb) disassemble 'k3::(anonymous namespace)::BM_AwaitLongReadyChain(testing::benchmark::State&)'
Dump of assembler code for function k3::(anonymous namespace)::BM_AwaitLongReadyChain(testing::benchmark::State&):
   [...]
   0x00000000003a416d <+45>:    call   0x3ad0e0 <k3::(anonymous namespace)::RecursivelyAwait<k3::(anonymous namespace)::Immediate17>(unsigned long, k3::(anonymous namespace)::Immediate17&&)>
End of assembler dump.

But if I ask GDB to disassemble it using the very same name that it refers to the function with, it claims the function doesn't exist:

(gdb) disassemble 'k3::(anonymous namespace)::RecursivelyAwait<k3::(anonymous namespace)::Immediate17>(unsigned long, k3::(anonymous namespace)::Immediate17&&)'
No symbol "k3::(anonymous namespace)::RecursivelyAwait<k3::(anonymous namespace)::Immediate17>(unsigned long, k3::(anonymous namespace)::Immediate17&&)" in current context.

However, if I disassemble it using its address, it works fine:

(gdb) disassemble 0x3ad0e0
Dump of assembler code for function k3::(anonymous namespace)::RecursivelyAwait<k3::(anonymous namespace)::Immediate17>(unsigned long, k3::(anonymous namespace)::Immediate17&&):
   0x00000000003ad0e0 <+0>:     push   rbp
  [...]
End of assembler dump.

This is terribly inconvenient, because I don't know the address a priori—I have to go disassemble a caller just to find the address of the callee. It's really cumbersome.

How can I get GDB to disassemble this function by name? I assume this is some issue with name mangling/canonicalization, probably around the rvalue references and/or anonymous namespaces, but I can't figure out what exactly is going on. I'm using GDB 10.0-gg5.


Solution

  • But if I ask GDB to disassemble it using the very same name that it refers to the function with, it claims the function doesn't exist

    1. There are many possible mangling schemes; the relationship between mangled and unmangled names is not 1:1.
    2. The parser built into GCC which turns foo::bar(int) into something which can be used to lookup the symbol in the symbol table may have bugs.

    This is terribly inconvenient, because I don't know the address a priori—I have to go disassemble a caller just to find the address of the callee.

    If the called function is already on the stack (i.e. part of active call chain), you can easily disassemble it via disas $any_address_in_fn -- you don't need to give GDB the starting address. So you could do e.g. frame 5 followed by disas $pc -- GDB will find enclosing function in the symbol table and disassemble it in its entirety.

    Another option is to get the address from file:line info: info line foo.cc:123 followed by disas $addr_given_by_previous_command.

    If you know that foo::bar() exists somewhere, but don't know its source location, another option is to set a breakpoint on it via e.g. rbreak 'foo::bar'. This will tell you the address where the breakpoint was set, and you can disassemble that address.