从gdb中的c ++ const ref中提取“对象内容”打印输出?

时间:2017-10-17 20:16:03

标签: python c++ debugging gdb

考虑以下示例,调用实例test-types-gdb-printout.cpp(在我当前的,更复杂的调试过程中模拟类似的情况):

#include <iostream>
#include <cstdio>

namespace Some { namespace Stuff {

template<typename Type>
class MyVect {
  public:
    MyVect();
    MyVect(Type x, Type y);
    Type AddComps();
    operator const Type*() const;
    operator Type*();
    Type x;
    Type y;
};

template<typename Type>
MyVect<Type>::MyVect() {
}
template<typename Type>
MyVect<Type>::MyVect(Type _x, Type _y) {
  x = _x;
  y = _y;
}
template<typename Type>
Type MyVect<Type>::AddComps() {
  return x+y;
}
template < typename Type >
MyVect< Type >::operator const Type*() const {
  return &x;
}
template < typename Type >
MyVect< Type >::operator Type*() {
  return &x;
}

typedef MyVect<int> MyVecti;
}}

int main() {
  Some::Stuff::MyVecti mvi(5,10);
  const Some::Stuff::MyVecti& mvic = mvi;
  Some::Stuff::MyVecti* mvip = new Some::Stuff::MyVecti(30,12);
  printf("Result is: %d ; then %d\n", mvi.AddComps(), mvip->AddComps()); // line 46
  delete mvip;
  return 0;
}

我用以下代码编译:

g++ -g test-types-gdb-printout.cpp -o test-types-gdb-printout.exe

...然后我在gdb调试器中运行它,如下所示:

$ gdb -ex "b test-types-gdb-printout.cpp:46" -ex "r" -ex "p mvi" -ex "p mvic" -ex "p mvip" --args ./test-types-gdb-printout.exe
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
Reading symbols from ./test-types-gdb-printout.exe...done.
Breakpoint 1 at 0x4007e7: file test-types-gdb-printout.cpp, line 50.
Starting program: /tmp/test-types-gdb-printout.exe 

Breakpoint 1, main () at test-types-gdb-printout.cpp:50
50    printf("Result is: %d ; then %d\n", mvi.AddComps(), mvip->AddComps());
$1 = {x = 5, y = 10}
$2 = (const Some::Stuff::MyVecti &) @0x7fffffffdc30: {x = 5, y = 10}
$3 = (Some::Stuff::MyVecti *) 0x602010
(gdb) 

请注意gdb,{I p rint:

  • mvi,类型为Some::Stuff::MyVecti,我只得到对象内容的打印输出(即其字段/属性名称和值) - 即{x = 5, y = 10}
  • mvip,这是Some::Stuff::MyVecti*类型的指针,我只得到地址的打印输出 - 即(Some::Stuff::MyVecti *) 0x602010
  • mvic,这是一个类型为const Some::Stuff::MyVecti&的const引用,我得到了地址和对象内容的打印输出 - 即(const Some::Stuff::MyVecti &) @0x7fffffffdc30: {x = 5, y = 10}

所以这就是事情:在我正在调试的实际程序中,在感兴趣的断点处,我确实有这种const引用。现在,我想在gdb的Python中使用对象内容printout 。我可以通过常规打印输出,例如gdb.execute("print...")

(gdb) python print(gdb.execute("print mvic"))
$4 = (const Some::Stuff::MyVecti &) @0x7fffffffdc30: {x = 5, y = 10}

....但这给了我地址(和类型) - 以及实际的对象内容打印输出。

现在,当然,鉴于我在Python中,我可以在那里解析字符串(通过在空格处拆分,或者更复杂的东西) - 但我想知道是否有任何方法只能获取对象内容打印输出{x = 5, y = 10}直接来自gdb(通过gdb.execute),或通过GDB Python API的某些专门方法?

1 个答案:

答案 0 :(得分:0)

Meh - 似乎答案已经存在于问题中 - 如果在变量属于实际类类型(即,不是ref,也不是指针)时打印“对象内容” - 那么只需尝试转换const引用到实际的班级,即:

(gdb) python print(gdb.execute("print (Some::Stuff::MyVecti)mvic"))
$7 = {x = 5, y = 10}

... 但是,请注意,这实际上并不是最终在Python中,只是gdb.execute将其输出转储到stdout,这可以通过以下方式证明:

(gdb) python print("AA" + str(gdb.execute("print (Some::Stuff::MyVecti)mvic")))
$9 = {x = 5, y = 10}      # this is on gdb level
AANone                    # this is from gdb's Python

...但是通过使用gdb.parse_and_eval

可以解决这个问题
(gdb) python print("AA"+str(gdb.parse_and_eval( "(Some::Stuff::MyVecti)mvic" )))
AA{x = 5, y = 10}

嗯,希望是这个问题......