gdb: how can I call operator char const*()?

Viewed 212

My class has operator const char*() const { return "foo"; }.

I have gdb 7.12.1-48.el7 stopped where a variable q is of this class.

I type p q. and when I hit the key I see a completion list of all its methods and members, including operator char const*.

However, I get this response to these commands.

(gdb) p q.operator char const*()
Couldn't find method MyClass::operatorconst char *

(gdb) p q.operator char const*
There is no member or method named operatorconst char *.

(gdb) p q.(operator char const*)
A syntax error in expression, near `(operator char const*)'.

(gdb) p q.(operator char const*)()
A syntax error in expression, near `(operator char const*)()'.

Any ideas on how I can call this method?

2 Answers

You can just use implicit conversion. For me p (const char*)q works in gdb 8.2.1:

(gdb) p (const char*)q
$2 = 0x7ffffffedaf0 "qwer"
(gdb)

Update to a simpler way thanks to Botje's comment above:

Given this code:

#include <cstdio>

class MyClass
{
    const char* const _name;
public:
    explicit MyClass( const char* const name ) : _name{name} {}
    operator const char*() const { return _name; }
    operator const char*()       { return _name + 1; } // Will omit the first char
};

int main()
{
    auto        c  = MyClass{"My name"};
    const auto& cc = c;
    std::puts(c);  // Prints 'y name'  since c is not const
    std::puts(cc); // Prints 'My name' since cc is const
}

Then in gdb, you can put a breakpoint on the puts() statement and do your print:

(gdb) p c.'operator char const*'()
$1 = 0x555555556005 "y name"
(gdb) p cc.'operator char const*'()
$2 = 0x555555556004 "My name"

This shows how to choose between the const and non-const versions of the function -- make the calling object const. (I think distinguishing between const-ness this may require a recent version of gdb. Version 9.1 shows the above. Version 7.11, as you can see on Coliru, always calls the const version.)


Old answer, kept for posterity:

You can call it (or other special or overloaded functions) using the mangled name. For instance:

#include <cstdio>

class MyClass
{
    const char* const _name;
public:
    explicit MyClass( const char* const name ) : _name{name} {}
    operator const char*() const { return _name; }
};

int main()
{
    auto c = MyClass{"My name"};
    std::puts(c);
}

Building that with gcc -ggdb -o test test.cpp, then running nm twice (once mangled and once demangled) will reveal the mangled name:

> nm test
...
00000000000011c6 W _ZN7MyClassC2EPKc
00000000000011e4 W _ZNK7MyClasscvPKcEv

> nm --demangle test
...
00000000000011c6 W MyClass::MyClass(char const*)
00000000000011e4 W MyClass::operator char const*() const

Special functions like constructors and operators are particularly obscure when mangled, but you can use other clues to find your target. Here, note the address of the function you want to call should match up in the mangled and demangled versions (also the order is probably the same).

Then in gdb, you can put a breakpoint on the puts() statement and do your print:

(gdb) p _ZNK7MyClasscvPKcEv(&c)
$2 = 0x555555556004 "My name"

Note that you need to pass in a this pointer as the first parameter, which in my case is the address of my object c.

Related