Packing is a way to arrange data in memory using padding technique to align data at a memory offset equal to multiple of a fix size (usual the word size, but it could be byte size, DWORD size or any other size). The purpose of packing is to align the data memory layout to the microprocessor’s addressing model, and this can help increase performance (in some microprocessor architectures, misaligned data is even not allowed at all). Furthermore, packing can also be used to eliminate cache false sharing issue by forcing individual data structure to occupy an entire cache line. This is very important in high performance/parallel computing domain and it become more and more relevant to everybody else because the industrial trend of moving towards multi-core processors machine.
Note: See more information about pack and alignment in [MSDN-PACK]. For more on false sharing see [WVC07] Chapter 8.2 and [PPP09] Chapter 1
In this case study, a heap bug is encountered due to incorrect use of the packing. The debugging technique demonstrated here includes some basic knowledge of Windows heap as described in last post and some understanding of data alignment in 64 bits Windows.
The Bug:
MyProgram is a 64-bit native application running under Windows 7, and it crashes consistently when it is launched. From the Event Viewer (Windows Logs/Application), the following error is logged:
Faulting application name: MyProgram.exe, version: 0.0.0.0, time stamp: 0x4b9d52d7
Faulting module name: ntdll.dll, version: 6.1.7600.16385, time stamp: 0x4a5be02b
Exception code: 0xc0000374
Fault offset: 0x00000000000c6cd2
Faulting process id: 0x1074
Faulting application start time: 0x01cac3bc0628969b
Faulting application path: d:\MyProgram\x64\Release\MyProgram.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
Report Id: 4485473b-2faf-11df-8d9f-00151736c5a7
The exception code 0xc0000374 means STATUS_HEAP_CORRUPTION. At this point, it is clear that this is a heap corruption bug, but it still requires some more debugging to find out the what actually corrupted the heap.
The Debugging:
As mentioned in last post, debugger could change the behavior of a heap related bug. Therefore, the –hd option is used during debugging so that the heap layout remains exactly the same as if the MyProgram.exe is running without debugger. In addition, the symbol path is set to Microsoft Public Symbol Server.
Note: –hd prevents the debugger to use the special heap which has a different layout than the default heap used by Windows.
The debugger outputs the following information when Windows Heap Manager detected the heap problem:
Critical error detected c0000374
(1364.dd4): Break instruction exception - code 80000003 (first chance)
ntdll!RtlUnhandledExceptionFilter+0x29f:
00000000`77bc6c9f cc int 3
With symbols loaded, uses command !heap to show more information, only the relevant outputs are shown
0:003> !heap
Details:
Error address: 00000000048b8410
Heap handle: 00000000048b0000
Error type heap_failure_buffer_overrun (6)
Last known valid blocks: before - 00000000048b8320, after - 00000000048b8fc0
Stack trace:
0000000077bca4a8: ntdll!RtlpAnalyzeHeapFailure+0x00000000000003a8
0000000077b5ea71: ntdll!RtlpAllocateHeap+0x0000000000002176
0000000077b529ac: ntdll!RtlAllocateHeap+0x000000000000016c
0000000071a6c887: msvcr90!malloc+0x000000000000005b
0000000071a6c987: msvcr90!operator new+0x000000000000001f
000007fef2fdbf55: MyProvider!CGenericThreadPool::Initialize+0x0000000000000135
000007fef2fd74c5: MyProvider!SpecialThreadPool::SpecialThreadPool+0x0000000000000075
000007fef2fcb5cc: MyProvider!CPolicyProvider::CPolicyProvider+0x00000000000000ac
000007fef2fd3e84: MyProvider!MyProviderInitialize+0x0000000000000034
000007fef308e043: MyProgram!Initialize+0x00000000000002a3
As the output indicates, the heap issue is a buffer overrun, and the address where this happens is at 00000000048b8410. From the stack trace, it is obvious that overrun happens inside some constructor calls and Windows Heap Manager detected it when RtlAllocateHeap is called.
Read more:
Brandon's Blog Posted via email from jasper22's posterous