我怎样才能看到C ++类如何在内存中使用gdb进行布局?

时间:2011-10-12 20:56:13

标签: c++ gdb

我有一个程序的调试版本(V8 JavaScript VM),我想了解某些类的实例是如何在内存中布局的。我可以漂亮地打印这样的结构:

(gdb) print thread_local
$6 = {
  blocks_ = {
    data_ = 0x868ceb0,
    capacity_ = 7,
    length_ = 1
  },
  entered_contexts_ = {
    data_ = 0x868d828,
    capacity_ = 1,
    length_ = 1
  },
  saved_contexts_ = {
    data_ = 0x868d838,
    capacity_ = 1,
    length_ = 1
  },
  spare_ = 0x0,
  ignore_out_of_memory_ = false,
  call_depth_ = 1,
  handle_scope_data_ = {
    next = 0x0,
    limit = 0x0,
    level = 0
  }
}

但是我想知道相对于对象的开始,那些不同的成员(块,entered_contexts等)在物理上的位置。在基于Solaris的系统上,mdb可以为C结构执行此操作,如下所示:

> ::print -at port_event_t
0 port_event_t {
    0 int portev_events 
    4 ushort_t portev_source 
    6 ushort_t portev_pad 
    8 uintptr_t portev_object 
    10 void *portev_user 
}

在该示例中,每个字段都以其与结构起点的偏移量为前缀。我想为C ++类做同样的事情。 gdb必须有这些信息才能打印出struct成员,但是有什么方法可以查看它吗?

或者,是否有其他方法可以为正在运行的程序执行此操作?

5 个答案:

答案 0 :(得分:4)

您可以随时打印出每个成员的地址,并this自行计算出来(使用&获取成员地址,就像语言本身一样)。

答案 1 :(得分:2)

我希望我知道。

您可以使用ptype列出成员。然后你可以像这样制造一个穷人的偏移:

(gdb) p/a &((my_struct_*)0)->my_member

(gdb) p/a &((struct sk_buff*)0)->iif
$7 = 0x74

答案 2 :(得分:0)

我所知道的唯一方法是x /<number of bytes>x <variable name>

这将为您提供十六进制转储,然后由您来阅读结构。

答案 3 :(得分:0)

使用pahole(不属于GDB)。

另一种可能性是pahole.py(尚未提交)。

答案 4 :(得分:0)

2020年,现代gdb版本的版本为ptype /o

(gdb) ptype /o 'sead::MethodTreeNode'
/* offset    |  size */  type = class sead::MethodTreeNode : public sead::IDisposer, public sead::TTreeNode<sead::MethodTreeNode*>, public sead::INamable {
                         private:
/*   88      |    32 */    class sead::StorageFor<sead::AnyDelegate> [with T = class sead::AnyDelegate] {
                             private:
/*   88      |    32 */        u8 mStorage[32];

                               /* total size (bytes):   32 */
                           } mDelegateHolder;
/*  120      |     8 */    class sead::CriticalSection *mCriticalSection;
/*  128      |     4 */    u32 mPriority;
/*  132      |     4 */    sead::BitFlag32 mPauseFlag;
/*  136      |     8 */    PauseEventDelegate *mPauseEventDelegate;
/*  144      |     8 */    void *mUserID;

                           /* total size (bytes):  152 */
                         }

它甚至还会向您显示成员变量的结构(即结构/类)和总大小。

记录下来,这是原始的C ++代码:

class MethodTreeNode : public IDisposer, public TTreeNode<MethodTreeNode*>, public INamable
{
    // ...
    using PauseEventDelegate = IDelegate2<MethodTreeNode*, PauseFlag>;
    // ...
    StorageFor<sead::AnyDelegate> mDelegateHolder;
    mutable CriticalSection* mCriticalSection;
    u32 mPriority;
    BitFlag32 mPauseFlag;
    PauseEventDelegate* mPauseEventDelegate;
    void* mUserID;
};

我还没有弄清楚如何使它以十六进制打印成员偏移量。