In GDB, what is the proper way to call C++ functions inside namespaces or classes in non-debug binaries?
Asked Answered
N

1

6

GDB's call command normally works great for calling functions, as long as the symbols are present. But if the function is in a namespace or a class, suddenly it won't work unless it was compiled with debugging information.

For example, let's say I have this program:

#include <iostream>

namespace ns {
    void test()
    {
        std::cout << "ns::test" << std::endl;
    }
}

struct cl {
    static void test()
    {
        std::cout << "cl::test" << std::endl;
    }
};

void func()
{
    std::cout << "func" << std::endl;
}

int main()
{
    ns::test();
    cl::test();
    func();
    return 0;
}

I saved that as test.cpp, compiled it with g++ test.cpp -o test, then started it inside GDB:

$ gdb test
GNU gdb (GDB) 11.1
[...]
Reading symbols from test...
(No debugging symbols found in test)
(gdb) start

Calling func from GDB works as expected:

(gdb) call (void)func()
func

The others, however, do not:

(gdb) call (void)ns::test()
No symbol "ns" in current context.
(gdb) call (void)cl::test()
No symbol "cl" in current context.

It works fine if it was compiled with -ggdb, but that's not usually an option if the source code is unavailable.

It's worth pointing out that GDB is aware of these functions and their addresses:

(gdb) info functions
...
0x0000000000001169  ns::test()
0x000000000000119b  func()
0x000000000000124e  cl::test()
...
(gdb) info symbol 0x1169
ns::test() in section .text
(gdb) break cl::test()
Breakpoint 1 at 0x1252

Those names will also autocomplete if I press Tab, even in a call command, meaning in that case it will autocomplete to something that doesn't work.

In addition, calling those functions works fine if I use their raw names:

(gdb) call (void)_ZN2ns4testEv()
ns::test
(gdb) call (void)_ZN2cl4testEv()
cl::test

So what's the deal here? Is this a bug in GDB, or is there some kind of special syntax I'm unaware of?

Newbill answered 8/10, 2021 at 7:1 Comment(2)
Try quoting the whole thing so GDB doesn't try to search for the nonexistent ns symbol. call (void)'ns::test'(). Also, GDB willl use the C calling convention, and that's OK in this case but not generally.Vasilek
@MarkPlotnick That worked; thanks a lot! Can you please post this as an answer so I can accept it?Newbill
V
8

Your C++ compiler kindly put ns::test into the symbol table. All we need to do is prevent GDB's expression evaluator from trying to look up the non-existent symbol ns. To do this, put the entire function name in single quotes.

(gdb) call (void)'ns::test'()
ns::test
Vasilek answered 9/10, 2021 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.