我在一个大型应用程序上工作,经常使用WinDbg来诊断基于客户的DMP文件的问题。我已经为WinDbg写了一些小扩展,这些扩展已经证明对于从DMP文件中提取信息位非常有用。在我的扩展代码中,我发现自己以相同的方式反复引用C++类对象,一次又一次地,手动。例如:如何基于WinDbg扩展中的转储文件内存创建对象?
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);
行之有效,但我已经写了更多的扩展,具有更强大的功能(和访问我们的应用DMP文件的更多复杂的对象),我渴望一个更好的解决方案。我当然可以访问我们自己的应用程序的源代码,所以我认为应该有一种方法可以将对象从DMP文件中复制出来,并使用该内存在调试器扩展中创建一个实际对象,以便我可以调用函数通过链接来自我们的应用程序的DLL)。这可以帮助我省去手工从DMP中取出东西的麻烦。
这甚至可能吗?我尝试了一些显而易见的事情,例如在扩展中创建一个新对象,然后直接从DMP文件中用一个大的ReadMemory覆盖它。这似乎将数据放在正确的字段中,但是当我试图调用一个函数时却吓坏了。我想我失去了一些东西......也许C++拉了一些我不知道的vtable时髦性?我的代码看起来与此类似:
SomeClass* thisClass = SomeClass::New();
ReadMemory(addressOfObj, &(*thisClass), sizeof(*thisClass), &cb);
后续:它看起来像从EngExtCpp可能ExtRemoteTyped是我想要的吗?有没有人成功使用过这个?我需要谷歌了一些示例代码,但没有多少运气。
跟帖2:我追求这一调查的两种不同的路线。
1)我期待到ExtRemoteTyped,但现在看来这个类是真的只是为ReadMemory/GetFieldOffset调用一个帮手。是的,这将有助于加快ALOT的速度,但对于从DMP文件重新创建对象并没有什么帮助。尽管文档很渺茫,所以我可能会误解某些东西。 2)我也在考虑尝试使用ReadMemory来使用DMP文件中的数据覆盖在扩展中创建的对象。但是,我并没有像上面那样使用sizeof(* thisClass),而是认为我只会挑选出数据元素,并保持vtable不变。
伟大的问题PJ! – 2010-04-04 21:52:01