【问题标题】:gdb: how can I call operator char const*()?gdb:如何调用运算符 char const*()?
【发布时间】:2020-09-29 12:22:03
【问题描述】:

我的班级有 operator const char*() const { return "foo"; }

我已经停止了 gdb 7.12.1-48.el7,其中变量 q 属于此类。

我输入p q.,当我按下键时,我会看到一个包含其所有方法和成员的完成列表,包括operator char const*

但是,我收到了对这些命令的响应。

(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*)()'.

关于如何调用此方法的任何想法?

【问题讨论】:

  • 即使是 gdb 9.1 也在为此苦苦挣扎。我不相信有办法做到这一点。从历史上看,gdb 对 C++ 的了解总是很少。真的不能怪这个可怜的野兽。除了成熟的 C++ 编译器之外,任何东西都无法解析 C++ 的语法。
  • 这能回答你的问题吗? calling operator<< in gdb 单引号似乎是关键。

标签: c++ gdb operators


【解决方案1】:

您可以只使用隐式转换。对我来说 p (const char*)q 在 gdb 8.2.1 中工作:

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

【讨论】:

    【解决方案2】:

    感谢Botje上面的评论,更新为更简单的方式

    鉴于此代码:

    #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
    }
    

    然后在 gdb 中,您可以在 puts() 语句上放置一个断点并进行打印:

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

    这显示了如何在函数的const 和非const 版本之间进行选择——使调用对象const。 (我认为区分 const-ness 这可能需要最新版本的 gdb。版本 9.1 显示了上述内容。版本 7.11,如您在 Coliru 上所见,始终调用 const版本。)


    旧答案,留作后人:

    您可以使用重命名的名称来调用它(或其他特殊或重载的函数)。例如:

    #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);
    }
    

    使用gcc -ggdb -o test test.cpp 构建它,然后运行nm 两次(一次被破坏和一次被解组)将显示被破坏的名称:

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

    构造函数和运算符等特殊函数在被破坏时特别模糊,但您可以使用其他线索找到您的目标。在这里,请注意您要调用的函数的地址应该在 mangled 和 demangled 版本中匹配(而且顺序可能相同)。

    然后在 gdb 中,您可以在 puts() 语句上放置一个断点并进行打印:

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

    请注意,您需要传入一个this 指针作为第一个参数,在我的例子中是我的对象c 的地址。

    【讨论】:

      猜你喜欢
      • 2014-07-28
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2011-08-27
      • 2019-03-25
      • 2022-01-15
      相关资源
      最近更新 更多