【发布时间】:2020-04-22 01:58:45
【问题描述】:
我正在尝试为我的 Windows 应用程序编写内存跟踪器。我已经使用 Detours 完成了一个原型。我连接了 HeapAlloc、HeapReAlloc、HeapFree、HeapDestroy 并输出了一些日志供我检查。但是有问题。
这是我的示例代码:
void thread_foo()
{
while(1)
{
void* tempPtr = HeapAlloc(GetProcessHeap(), 0, 3);
Sleep(50);
}
}
int main()
{
std::thread tobj(thread_foo);
int size = 16;
tobj.join();
}
这是我的跟踪输出(前 32 行,格式为 ALLOC/FREE/REALLOC/DESTROY:时间戳、调用堆栈哈希、堆指针、标志、大小、结果指针):
ALLOC:2736795824738, -592122872, 0000019110690000, 0, 256, 000001911069E130
ALLOC:2736795825084, 1232708493, 0000019110690000, 0, 16, 000001911069F0A0
ALLOC:2736795825225, -929256262, 0000019110690000, 0, 56, 000001911069FAF0
ALLOC:2736795825284, -929523462, 0000019110690000, 0, 2, 000001911069FBF0
ALLOC:2736795825323, 151458640, 0000019110690000, 0, 2, 000001911069FBF0
ALLOC:2736795825369, -929340699, 0000019110690000, 0, 16, 000001911069F200
ALLOC:2736795825404, 1203567881, 0000019110690000, 0, 48, 000001911069F570
ALLOC:2736795825436, 1789431341, 0000019110690000, 8, 344, 000001911069FC10
ALLOC:2736795825511, -1394565794, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825573, 955998638, 0000019110690000, 0, 6, 000001911069E240
ALLOC:2736795825600, -958719147, 0000019110690000, 0, 2, 000001911069E260
ALLOC:2736795825625, 955994058, 0000019110690000, 8, 4, 000001911069E280
ALLOC:2736795825651, 1789431550, 0000019110690000, 8, 344, 000001911069E2A0
ALLOC:2736795825677, -1394565585, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825714, 955998680, 0000019110690000, 0, 6, 000001911069E280
ALLOC:2736795825736, 122263169, 0000019110690000, 0, 2, 000001911069E240
ALLOC:2736795825761, 1203256005, 0000019110690000, 8, 512, 000001911069E400
ALLOC:2736795825786, 955996289, 0000019110690000, 8, 4, 000001911069E610
ALLOC:2736795825810, 1789433781, 0000019110690000, 8, 344, 000001911069FC10
ALLOC:2736795825834, -1394563354, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825868, 956000911, 0000019110690000, 0, 6, 000001911069E610
ALLOC:2736795825893, 1203615483, 0000019110690000, 0, 16, 000001911069F140
ALLOC:2736795825921, 1232708730, 0000019110690000, 0, 16, 000001911069F160
ALLOC:2736795825945, -929316070, 0000019110690000, 0, 16, 000001911069F260
ALLOC:2736795825968, 1232708941, 0000019110690000, 0, 16, 000001911069F1A0
ALLOC:2736795825990, -929340251, 0000019110690000, 0, 16, 000001911069F2A0
ALLOC:2736795826013, 1232709165, 0000019110690000, 0, 16, 000001911069F0C0
ALLOC:2736795826033, -929340027, 0000019110690000, 0, 16, 000001911069F100
ALLOC:2736795826066, 151797360, 0000019110690000, 0, 16, 000001911069F120
ALLOC:2736795826106, -929229531, 0000019110690000, 0, 16, 000001911069F2C0
ALLOC:2736795826131, 1203787877, 0000019110690000, 0, 96, 000001911069E240
ALLOC:2736795826158, 1789651341, 0000019110690000, 8, 344, 000001911069FD70
问题是第4行和第5行,我们可以看到,得到的是同一个指针。它们之间没有 HeapFree 或 HeapDestroy。而这 2 个 HeapAlloc 不是我的调用,我可以通过大小来确定。我假设它们与 std::thread 相关。他们不是唯一的一对。第9、14、20、32行也一样。
如果删除与线程相关的代码,只需在main() 中调用thread_foo(),一切都会恢复正常。
有人知道吗?
P.S.如果有人关心挂钩代码,它只是基于https://github.com/microsoft/Detours/blob/master/samples/tracemem/trcmem.cpp
我添加了挂钩 HeapReAlloc、HeapFree、HeapDestroy 并将日志收集到文件。
全部清除!全部清除!
我找到了原因。原因是虽然我钩住了HeapFree,但所有由delete 或free() 释放的内存并没有调用我封装的HeapFree。我不知道为什么,但事实就是这样。现在我也钩了CRT free(),之前隐藏的free消息出来了。
因此,我更改了这个问题的标题。希望有人对此有所了解。
【问题讨论】:
-
我不知道 detours 库,但您的代码可能存在的一个问题是
join()永远不会返回,因此main()中的其余代码应该被任何体面的优化器删除. -
@TedLyngmo 谢谢,你说得对。我将删除这些代码以避免歧义。
-
我们需要查看您的钩子的代码。最有可能的是,它有问题。例如,它是线程安全的吗?
-
@PaulSanders 在 Detours 4.0.1 中,有一个名为“tracemem”的示例,我的挂钩代码基于该示例,我认为没什么特别的。
标签: c++ windows malloc detours heapalloc