所以我使用了HeapWalk函数的this示例将它实现到我的应用程序中。我玩了一下,当我添加
时看到了HANDLE d = HeapAlloc(hHeap, 0, sizeof(int));
int* f = new(d) int;
创建堆后,将记录一些新输出:
Allocated block Data portion begins at: 0X037307E0
Size: 4 bytes
Overhead: 28 bytes
Region index: 0
因此,我认为我可以检查Entry.wFlags
以查看它是否设置为PROCESS_HEAP_ENTRY_BUSY
,以便跟踪我在堆上使用的已分配内存量。所以我有:
HeapLock(heap);
int totalUsedSpace = 0, totalSize = 0, largestFreeSpace = 0, largestCounter = 0;
PROCESS_HEAP_ENTRY entry;
entry.lpData = NULL;
while (HeapWalk(heap, &entry) != FALSE)
{
int entrySize = entry.cbData + entry.cbOverhead;
if ((entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
{
// We have allocated memory in this block
totalUsedSpace += entrySize;
largestCounter = 0;
}
else
{
// We do not have allocated memory in this block
largestCounter += entrySize;
if (largestCounter > largestFreeSpace)
{
// Save this value as we've found a bigger space
largestFreeSpace = largestCounter;
}
}
// Keep a track of the total size of this heap
totalSize += entrySize;
}
HeapUnlock(heap);
当在调试模式下构建时,这似乎有效(totalSize
和totalUsedSpace
是不同的值)。但是,当我在发布模式下运行时,totalUsedSpace
始终为0.
我在发布模式下使用调试器逐步完成它,并且对于每个堆它循环三次,我在entry.wFlags
中通过调用HeapWalk
得到以下标志:
1 (PROCESS_HEAP_REGION)
0
2 (PROCESS_HEAP_UNCOMMITTED_RANGE)
然后退出while
循环,GetLastError()按预期返回ERROR_NO_MORE_ITEMS
。
从here我发现0
的标志值是&#34;提交的块是免费的,即没有被分配或者没有被用作控制结构。&#34; < / p>
有人知道为何在内置发布模式时无法正常工作吗?我对计算机处理内存的方式不太了解,所以我不确定错误的来源。在Google上搜索并没有想出任何东西,所以希望有人在这里知道。
更新:我自己仍在调查此问题,如果我使用vmmap监控应用程序,我可以看到该进程有9个堆,但是当调用GetProcessHeaps
时,它返回有22个堆。此外,它返回的任何堆句柄都不会匹配GetProcessHeap()
或_get_heap_handle()
的返回值。似乎GetProcessHeaps
的行为不符合预期。以下是获取堆列表的代码:
// Count how many heaps there are and allocate enough space for them
DWORD numHeaps = GetProcessHeaps(0, NULL);
HANDLE* handles = new HANDLE[numHeaps];
// Get a handle to known heaps for us to compare against
HANDLE defaultHeap = GetProcessHeap();
HANDLE crtHeap = (HANDLE)_get_heap_handle();
// Get a list of handles to all the heaps
DWORD retVal = GetProcessHeaps(numHeaps, handles);
retVal
与numHeaps
的值相同,表示没有错误。
答案 0 :(得分:0)
之前已经设置了应用程序验证程序来执行整页堆验证我的可执行文件并干扰GetProcessHeaps
返回的堆。我忘记了它的设置,因为它是在几天前针对另一个问题完成的,然后在没有清除测试的情况下关闭。调试版本中没有发生这种情况,因为应用程序构建为调试版本的不同文件名。
我们通过添加断点并查看线程的callstack来设法检测到这一点。我们可以看到AV DLL已被注入并让我们知道在哪里看。