C++ HeapWalk块枚举返回不在堆中的地址

C++ HeapWalk块枚举返回不在堆中的地址,c++,c,windows,memory,heap,C++,C,Windows,Memory,Heap,背景:在我的工作(运行Windows XP Embedded的工业CNC机器)中,我们有一个进程,通过使用VirtualAlloc和VirtualLock系列函数将所有内存锁定到物理RAM中 我知道,在这一点上,将内存锁定到物理RAM可能不会带来以前的好处(在以前的Windows版本中,如NT),但我们正面临一个最后期限,因此,尽管我们可能能够在将来研究删除它,但目前这是一个困难的要求 因此,最近我对该进程使用的dll进行了更改,这反过来带来了更多dll,其中一些dll创建了自己的堆(除了进程加

背景:在我的工作(运行Windows XP Embedded的工业CNC机器)中,我们有一个进程,通过使用VirtualAlloc和VirtualLock系列函数将所有内存锁定到物理RAM中

我知道,在这一点上,将内存锁定到物理RAM可能不会带来以前的好处(在以前的Windows版本中,如NT),但我们正面临一个最后期限,因此,尽管我们可能能够在将来研究删除它,但目前这是一个困难的要求

因此,最近我对该进程使用的dll进行了更改,这反过来带来了更多dll,其中一些dll创建了自己的堆(除了进程加载的其他库中已经创建的堆之外)

代码(psuedocode)的基本结构为:

因此,这是伪代码,实现是用C编写的(我在每次调用Windows函数时都使用GetLastError和FormatMessage进行了正确的错误检查)

好的,所以问题是,以前,被锁定的大小是数据块大小和块开销的总和,但是使用的ptr是块中数据的ptr,所以有些情况下,VirtualAlloc和VirtualLock会重叠,越过堆进入下一堆,并因无效内存访问而失败

在我修复了这个问题之后,现在有一个块在第二次VirtualAlloc(使用MEM_COMMIT)期间失败,并出现了相同的“无效内存访问”错误

“heap\u entry”结构中给出的地址是0x00b00020。奇怪的是,根据SysInternals工具VMMap(到目前为止,它在帮助我诊断之前的问题时精确到字节)报告堆本身从0xA40000到0xA50000,但是从HeapWalk函数返回的地址是0xb00020,这是完全错误的

事实上,最后两个块超过0xA50000范围:

ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a46f50->00a47163|560 bytes) of heap 5 (532 byte block, 28 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a46f50->00a47163|560 bytes) of heap 5
Heap 5 handle 10747904 start address 00a47188 size 3704 overhead 16 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a47188->00a47fff|3720 bytes) of heap 5 (3704 byte block, 16 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a47188->00a47fff|3720 bytes) of heap 5
Heap 5 handle 10747904 start address 00a48000 size 32768 overhead 0 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a48000->00a4ffff|32768 bytes) of heap 5 (32768 byte block, 0 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a48000->00a4ffff|32768 bytes) of heap 5
Heap 5 handle 10747904 start address 00a60020 size 589856 overhead 0 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a60020->00af003f|589856 bytes) of heap 5 (589856 byte block, 0 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a60020->00af003f|589856 bytes) of heap 5
Heap 5 handle 10747904 start address 00b00020 size 589862 overhead 250 
ppi1: LockInMemory: VirtualAlloc: Failed to Commit memory (00b00020->00b90045|590112 bytes) of heap 5: (Windows Error 487) Attempt to access invalid address. (589862 byte block, 250 bytes overhead, flags: 0x00000004)
如您所见,它一直保持在0xA40000范围内,直到出于某种原因到达0xA60000->0xAF0000范围,然后转到0xB00020地址

我很困惑。无论是否在块枚举期间锁定堆,此问题都会持续存在。并且标志is has set表示分配了块

好吧,我会逐一锁定。也许我应该一次把它们都锁上?此物理内存锁定仅在应用程序初始化期间发生

有人知道这里会发生什么吗?我很困惑,想不出其他方法来获取更多信息

ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a46f50->00a47163|560 bytes) of heap 5 (532 byte block, 28 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a46f50->00a47163|560 bytes) of heap 5
Heap 5 handle 10747904 start address 00a47188 size 3704 overhead 16 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a47188->00a47fff|3720 bytes) of heap 5 (3704 byte block, 16 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a47188->00a47fff|3720 bytes) of heap 5
Heap 5 handle 10747904 start address 00a48000 size 32768 overhead 0 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a48000->00a4ffff|32768 bytes) of heap 5 (32768 byte block, 0 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a48000->00a4ffff|32768 bytes) of heap 5
Heap 5 handle 10747904 start address 00a60020 size 589856 overhead 0 
ppi1: LockInMemory: VirtualAlloc: Successfully Commit memory (00a60020->00af003f|589856 bytes) of heap 5 (589856 byte block, 0 bytes overhead)
ppi1: LockInMemory: VirtualLock: Successfully Locked memory (00a60020->00af003f|589856 bytes) of heap 5
Heap 5 handle 10747904 start address 00b00020 size 589862 overhead 250 
ppi1: LockInMemory: VirtualAlloc: Failed to Commit memory (00b00020->00b90045|590112 bytes) of heap 5: (Windows Error 487) Attempt to access invalid address. (589862 byte block, 250 bytes overhead, flags: 0x00000004)