如何在WinDbg扩展中基于转储文件内存创建对象?

pj4*_*533 5 c++ minidump memory-dump windbg object

我处理大型应用程序,并经常使用WinDbg根据客户的DMP文件诊断问题.我已经为WinDbg编写了一些小扩展,这些扩展已被证明对于从DMP文件中提取信息非常有用.在我的扩展代码中,我发现自己一遍又一遍地手动取消引用c ++类对象.例如:

Address = GetExpression("somemodule!somesymbol");
ReadMemory(Address, &addressOfPtr, sizeof(addressOfPtr), &cb);

// get the actual address
ReadMemory(addressOfObj, &addressOfObj, sizeof(addressOfObj), &cb);

ULONG offset;
ULONG addressOfField;

GetFieldOffset("somemodule!somesymbolclass", "somefield", &offset);
ReadMemory(addressOfObj+offset, &addressOfField, sizeof(addressOfField), &cb);
Run Code Online (Sandbox Code Playgroud)

这很好,但是由于我已经编写了更多扩展,具有更强大的功能(以及在我们的应用程序DMP文件中访问更复杂的对象),我渴望得到更好的解决方案.我当然可以访问我们自己的应用程序的源代码,所以我认为应该有一种方法可以从DMP文件中复制一个对象并使用该内存在调试器扩展中创建一个我可以调用函数的实际对象(通过我们的应用程序中的dll链接).这样可以省去手动拉出DMP的麻烦.

这甚至可能吗?我尝试了一些显而易见的事情,比如在扩展中创建一个新对象,然后直接从DMP文件用一个大的ReadMemory覆盖它.这似乎把数据放在了正确的字段中,但当我试图调用函数时吓坏了.我想我错过了一些东西...也许c ++拉出一些我不知道的vtable funky-ness?我的代码看起来类似于:

SomeClass* thisClass = SomeClass::New();
ReadMemory(addressOfObj, &(*thisClass), sizeof(*thisClass), &cb);
Run Code Online (Sandbox Code Playgroud)

关注:看起来像EngExtCpp的POSSIBLY ExtRemoteTyped是我想要的吗?有没有人成功使用过这个?我需要谷歌一些示例代码,但没有太多运气.

关注2:我正在对此进行两种不同的调查.
1)我正在研究ExtRemoteTyped,但看起来这个类实际上只是ReadMemory/GetFieldOffset调用的帮助器.是的,它有助于加速ALOT,但在从DMP文件重新创建对象时并没有真正帮助.虽然文档很小,但我可能会误解一些东西.2)我也在尝试使用ReadMemory用来自DMP文件的数据覆盖在我的扩展中创建的对象.但是,我没有像上面那样使用sizeof(*thisClass),而是认为我只会选择数据元素,并保持vtable不变.

Mic*_*urr 1

有趣的想法,但这希望只适用于最简单的对象。例如,如果对象包含对其他对象(或虚函数表)的指针或引用,那么它们将无法很好地复制到新的地址空间。

但是,您也许能够获得一个“代理”对象来工作,当您调用代理方法时,它们会进行适当的调用以ReadMemory()获取信息。这听起来是一项相当大的工作,我认为它或多或少必须是您想要代理的每个类的自定义代码集。可能有更好的方法来解决这个问题,但这就是我突然想到的。