我有一个程序的调试版本(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成员,但是有什么方法可以查看它吗?
或者,是否有其他方法可以为正在运行的程序执行此操作?
答案 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)
答案 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;
};
我还没有弄清楚如何使它以十六进制打印成员偏移量。