Home > Mobile >  In GDB, what is the proper way to call C functions inside namespaces or classes in non-debug binar
In GDB, what is the proper way to call C functions inside namespaces or classes in non-debug binar

Time:10-08

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?

CodePudding user response:

This is not a bug in GDB. The debugger is not a C compiler, it does not know about the original C sources and does not know a call context or scope without debug info.

Imaging you have the code

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

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

And you are debugging the function cl::ns::test, i.e. the the current scope is the body of this function. You call (void)ns::test(). How can GDB, not being a compiler and not seeing the code, know the resolution scope and call cl::ns::test() instead of ns::test()? This information is in the debug info. You know already the proper way of the call, this is the mangled name.

info functions just shows demangled names. call requires mangled names for proper names to addresses resolutions, if no debug info is available.

Have you tried call (void)::ns::test()? It may be supported, since there is no ambiguity for GDB. I can't check it now.

CodePudding user response:

The scope figures there seem to be inconsequential since the ns::test and members in struct were not evaluated.

Since there happens to name mangling (encoding functions and variable names to unique names), as you can see it is encoding scopes, ns in (_ZN2ns4testEv) and cl in (_ZN2cl4testEv) into unique names.

Whereas even after name mangling the outside functions might be of the same name. (check once) ultimately it is invalidating scopes.

  • Related