The gflags was configured to only have "Enable heap tail checking" enabled. The PageHeap was not enabled.
c:\Program Files (x86)\Windows Kits\10\Debuggers\x64>gflags /i test.exe
Current Registry Settings for test.exe executable are: 00000010
htc - Enable heap tail checking
In the program below, a 4 bytes integer was allocated off the heap which was using 16 bytes alignment. So the rest of 12 bytes are filled with marker bytes.
int main()
{
int *p = new int{};
for (size_t i = 0; i < 16; ++i)
{
((char*)p)[i] = '0';
cout << ((char*)p)[i] << endl;
}
delete p;
cout << "After delete\n";
return 0;
}
And per MSFT, this is pretty straightforward.
This flag adds a short pattern to the end of each allocation. The Windows heap manager detects the pattern when the block is freed and, if the block was modified, the heap manager breaks into the debugger.
However, this was not happening. The buffer overrun was not captured and the process finished successfully.
Memory layout before the loop, starting from the address of the allocated integer. The rest 12 bytes were filled w/ specific byte patterns ab ab ..
which is correct.
This is after the loop was executed. The 12 bytes pattern was overrun.
This is after the memory block was released.
There was no exception, no debugger kick-in. And the message after delete
was also printed successfully.
Note: If I enabled the PageHeap at the same time, this same tail buffer overrun problem (I'm sure it didn't overrun into the next page protected by PageHeap of course) was then captured.
Is this a bug in heap manager? I think "Enable heap tail checking" and PageHeap are two independent features.