2017-10-17 68 views
0

考虑下面的例子,呼吁例如test-types-gdb-printout.cpp(其模拟了类似的情况,我目前更复杂,调试过程):从gdb的C++ const ref中提取“对象内容”打印输出?

#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,当我p RINT:

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

所以这是一点:在实际的程序,我调试,在感兴趣的断点,我有整整这种const引用。现在,我想使用对象内容打印输出只有 - 但在gdb的Python。就在普通打印输出,我可以在Python与获得,也就是说,gdb.execute("print...")

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

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

现在,当然,考虑到我在Python中,我可以在那里解析字符串(或者通过在空格处分割,或者更复杂一些) - 但是我想知道是否有任何方法只能获得可以直接从gdb(通过gdb.execute)或通过GDB Python API的某种特定方法打印对象内容{x = 5, y = 10}

回答

0

梅 - 似乎答案已经在问题中 - 如果在变量是实际类类型(即,不是引用或指针)时打印“对象内容” - 则只需尝试将常量裁判实际的类,即:

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

... 然而,注意,这实际上并不在Python结束了,这简直就是gdb.execute倾销其输出到标准输出,可以由被证明:

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

好,希望这个问题是它...