DynamoRIO / drmemory

Memory Debugger for Windows, Linux, Mac, and Android
Other
2.41k stars 256 forks source link

unhandled heap routine RtlAllocateMemoryZone #318

Open derekbruening opened 9 years ago

derekbruening commented 9 years ago

From bruen...@google.com on March 03, 2011 12:00:29

unit_tests w/ ResourceDispatcherHostTest disabled:

[----------] 13 tests from AudioRendererHostTest [ RUN ] AudioRendererHostTest.CreateAndClose :::Dr.Memory::: unhandled heap routine RtlAllocateMemoryZone

0:001> kn 30

ChildEBP RetAddr

00 222b9410 6a961eac ntdll!NtRaiseHardError+0x12 01 222b9454 6a94bbfa dynamorio!nt_messagebox+0x7c [c:\src\dr\git\src\core\win32\ntdll.c @ 3253] 02 222b9d64 100a3902 dynamorio!dr_messagebox+0x8a [c:\src\dr\git\src\core\x86\instrument.c @ 3005] 03 222b9f08 100aff8f drmemorylib!handle_alloc_pre_ex+0xf82 [c:\src\drmemory\git\src\common\alloc.c @ 3995] 04 222b9f3c 20fd4c26 drmemorylib!handle_alloc_pre+0x22f [c:\src\drmemory\git\src\common\alloc.c @ 4006] WARNING: Frame IP not in any known module. Following frames may be wrong. 05 2288ec44 730dcd41 0x20fd4c26 06 2288ec6c 730dccf4 AUDIOSES!AERTCreateHeap+0x21 07 2288ec88 730dcbfc AUDIOSES!AERTMemoryInitialize+0x1f 08 2288eca8 77d5bfe4 AUDIOSES!InitAudioClient+0x4f 09 2288ecc4 7591d82f ntdll!RtlRunOnceExecuteOnce+0x33 0a 2288ecdc 730d4a4d kernel32!InitOnceExecuteOnce+0x17 0b 2288ecfc 732d4840 AUDIOSES!DllGetClassObject+0x25 0c 2288ed44 732d21b0 MMDevAPI!GetIUnknownFromDll+0x1df 0d 2288ed5c 22f4bef8 MMDevAPI!MMDeviceGetPolicyConfig+0x1c 0e 2288ed9c 22f4476d wdmaud!CSessMixer::Initialize+0xb1 0f 2288edd0 22f442f7 wdmaud!CMixerDriver::GetMixer+0xaf 10 2288edec 22f448a2 wdmaud!mxdMessageThread+0x76 11 2288ee2c 74cf8472 wdmaud!mxdMessageBase+0x47 12 2288ee64 74cf853b WINMM!wdmDrvInstall+0x2aa 13 2288ee8c 74cf8679 WINMM!wdmDriverLoadClass+0x6f 14 2288eea8 74cf85da WINMM!wdmDriverLoadAllClasses+0xa3 15 2288eec0 74cf5557 WINMM!wdmPnpUpdateDriver+0x3e 16 2288eef0 74d0016d WINMM!ClientPnpChange+0xc4 17 2288ef1c 74cf460e WINMM!ClientUpdatePnpInfo+0x16e 18 2288ef58 00ffe606 WINMM!waveOutOpen+0x9f 19 2288ef84 0100193a unit_tests!PCMWaveOutAudioOutputStream::Open+0x66 [c:\src\chromium\src\media\audio\win\waveout_output_win.cc @ 131] 1a 2288efa0 010014d6 unit_tests!AudioOutputDispatcher::CreateAndOpenStream+0x7a [c:\src\chromium\src\media\audio\audio_output_dispatcher.cc @ 91] 1b 2288f04c 010007a2 unit_tests!AudioOutputDispatcher::StreamOpened+0xa6 [c:\src\chromium\src\media\audio\audio_output_dispatcher.cc @ 31] 1c 2288f198 00fefbc5 unit_tests!AudioOutputProxy::Open+0x102 [c:\src\chromium\src\media\audio\audio_output_proxy.cc @ 31] 1d 2288f2f4 00ff14d3 unit_tests!media::AudioOutputController::DoCreate+0x195 [c:\src\chromium\src\media\audio\audio_output_controller.cc @ 161] 1e 2288f314 00ff0ab5 unit_tests!DispatchToMethod<media::AudioOutputController,void (__thiscall media::AudioOutputController::)(AudioParameters),AudioParameters>+0x33 [c:\src\chromium\src\base\tuple.h @ 551] 1f 2288f330 01853a60 unit_tests!RunnableMethod<media::AudioOutputController,void (__thiscall media::AudioOutputController::)(AudioParameters),Tuple1 >::Run+0x35 [c:\src\chromium\src\base\task.h @ 331] 20 2288f41c 01853b95 unit_tests!MessageLoop::RunTask+0x110 [c:\src\chromium\src\base\message_loop.cc @ 367] 21 2288f42c 018546ac unit_tests!MessageLoop::DeferOrRunPendingTask+0x35 [c:\src\chromium\src\base\message_loop.cc @ 379] 22 2288f468 018d0af3 unit_tests!MessageLoop::DoWork+0xec [c:\src\chromium\src\base\message_loop.cc @ 569] 23 2288f554 018538a7 unit_tests!base::MessagePumpDefault::Run+0xc3 [c:\src\chromium\src\base\message_pump_default.cc @ 23] 24 2288f610 0185367e unit_tests!MessageLoop::RunInternal+0xf7 [c:\src\chromium\src\base\message_loop.cc @ 342] 25 2288f61c 01852f8a unit_tests!MessageLoop::RunHandler+0x2e [c:\src\chromium\src\base\message_loop.cc @ 316] 26 2288f644 01870c06 unit_tests!MessageLoop::Run+0x3a [c:\src\chromium\src\base\message_loop.cc @ 240] 27 2288f650 01870e07 unit_tests!base::Thread::Run+0x16 [c:\src\chromium\src\base\threading\thread.cc @ 129] 28 2288f82c 01878aa0 unit_tests!base::Thread::ThreadMain+0x107 [c:\src\chromium\src\base\threading\thread.cc @ 164] 29 2288f844 75903677 unit_tests!base::`anonymous namespace'::ThreadFunc+0x60 [c:\src\chromium\src\base\threading\platform_thread_win.cc @ 37] 2a 2288f850 77d59f02 kernel32!BaseThreadInitThunk+0xe

Original issue: http://code.google.com/p/drmemory/issues/detail?id=318

derekbruening commented 9 years ago

From timurrrr@google.com on June 22, 2011 05:07:34

This also fires on chrome.exe when browsing to www.google.com

derekbruening commented 9 years ago

From bruen...@google.com on October 26, 2011 13:34:47

also hit on media_unittests (which makes me wonder how the bot is running them: times look too fast to be under drmem):

[ RUN ] AudioOutputControllerTest.CreateAndClose Dr.M unhandled heap routine RtlAllocateMemoryZone

derekbruening commented 9 years ago

From bruen...@google.com on November 16, 2011 12:55:24

0:001> U @@(call_site) ntdll!RtlCreateMemoryBlockLookaside+0xe0: 77d8bd33 e8d8420800 call ntdll!RtlAllocateMemoryZone (77e10010)

0:001> Uf AUDIOSES!AERTCreateHeap AUDIOSES!AERTCreateHeap: 730dcd20 8bff mov edi,edi 730dcd22 55 push ebp 730dcd23 8bec mov ebp,esp 730dcd25 51 push ecx 730dcd26 56 push esi 730dcd27 57 push edi 730dcd28 ff7510 push dword ptr [ebp+0x10] 730dcd2b 33f6 xor esi,esi 730dcd2d ff750c push dword ptr [ebp+0xc] 730dcd30 8d45fc lea eax,[ebp-0x4] 730dcd33 ff7508 push dword ptr [ebp+0x8] 730dcd36 8975fc mov [ebp-0x4],esi 730dcd39 56 push esi 730dcd3a 50 push eax 730dcd3b ff15a4100d73 call dword ptr [AUDIOSES!_imp__RtlCreateMemoryBlockLookaside (730d10a4)]

hmmm, Allocate vs Create: ntdll!RtlAllocateMemoryZone ntdll!RtlAllocateMemoryBlockLookaside

RtlAllocateMemoryZone doesn't seem to do much RtlCreateMemoryZone calls NtAllocateVirtualMemory

RtlCreateMemoryBlockLookaside calls RtlCreateMemoryZone and then RtlAllocateMemoryZone

AUDIOSES!AERTDestroyZoneHeap+0x45: 730d1c38 ff7508 push dword ptr [ebp+0x8] 730d1c3b ff15bc100d73 call dword ptr [AUDIOSES!_imp__RtlDestroyMemoryZone (730d10bc)]

RtlDestroyMemoryZone calls NtFreeVirtualMemory

Owner: ---

derekbruening commented 9 years ago

From bruen...@google.com on November 16, 2011 12:57:13

*\ TODO ASSERT(pt->valloc_type == MEM_DECOMMIT || !is_in_heap_region(base), "heap region tracking bug");

this is after marking Zone and BlockLookaside as ignorable, but RtlCreateMemoryZone is a heap routine:

it ends up complaining about a VirtualFree of a reservation inside a heap region:

00 326193d0 6a961eac ntdll!NtRaiseHardError+0x12 01 32619414 6a94bbfa dynamorio!nt_messagebox+0x7c [c:\src\dr\git\src\core\win32\ntdll.c @ 3253] 02 32619d24 10101bac dynamorio!dr_messagebox+0x8a [c:\src\dr\git\src\core\x86\instrument.c @ 3005] 03 32619d30 10101bd6 drmemorylib!wait_for_user+0xc [c:\src\drmemory\git\src\common\utils.c @ 72] 04 32619d3c 100a0473 drmemorylib!drmemory_abort+0x16 [c:\src\drmemory\git\src\common\utils.c @ 95] 05 32619df4 1009f3a7 drmemorylib!handle_post_vfree+0x973 [c:\src\drmemory\git\src\common\alloc.c @ 2442] 06 32619e48 100d8075 drmemorylib!handle_post_alloc_syscall+0x457 [c:\src\drmemory\git\src\common\alloc.c @ 2493] 07 32619f34 6a94ad19 drmemorylib!event_post_syscall+0x45 [c:\src\drmemory\git\src\drmemory\syscall.c @ 793] 08 32619f68 6a958fcd dynamorio!instrument_post_syscall+0x99 [c:\src\dr\git\src\core\x86\instrument.c @ 1681] 09 32619f94 6a8fa1d5 dynamorio!post_system_call+0x75d [c:\src\dr\git\src\core\win32\syscall.c @ 3662] 0a 32619f9c 6a8fab80 dynamorio!handle_post_system_call+0x25 [c:\src\dr\git\src\core\dispatch.c @ 1839] 0b 32619fbc 6a8fac32 dynamorio!dispatch_enter_dynamorio+0x3f0 [c:\src\dr\git\src\core\dispatch.c @ 715] 0c 32f1f670 730d1c41 dynamorio!dispatch+0x12 [c:\src\dr\git\src\core\dispatch.c @ 148] 0d 32f1f688 730d1ccb AUDIOSES!AERTDestroyZoneHeap+0x4e 0e 32f1f6b4 730dd4c2 AUDIOSES!CCrossProcessBaseEndpoint::~CCrossProcessBaseEndpoint+0x2f 0f 32f1f6dc 730dd435 AUDIOSES!CCrossProcessClientOutputEndpoint::~CCrossProcessClientOutputEndpoint+0x1a 10 32f1f6e8 730d1b3e AUDIOSES!ATL::CComObject::vector deleting destructor'+0xd 11 32f1f6fc 730dd51d AUDIOSES!ATL::CComObject<CCrossProcessClientOutputEndpoint>::Release+0x2a 12 32f1f708 730dd4e5 AUDIOSES!CAudioClientStream::~CAudioClientStream+0x1f 13 32f1f714 730dd048 AUDIOSES!CAudioClientStream::scalar deleting destructor'+0xd 14 32f1f760 730dce07 AUDIOSES!CAudioClient::FinalRelease+0xc9 15 32f1f768 730dcdbb AUDIOSES!ATL::CComObject::~CComObject+0x33 16 32f1f774 730dcda1 AUDIOSES!ATL::CComObject::`vector deleting destructor'+0xd 17 32f1f788 7283ea0d AUDIOSES!ATL::CComObject::Release+0x27 18 32f1f798 728400d6 wdmaud!CWaveHandle::_Close+0x4d 19 32f1f7a4 7283e6f7 wdmaud!CWaveInHandle::_Close+0x1e 1a 32f1f7ac 7283512e wdmaud!CResetAudioJob::Work+0x6b 1b 32f1f7cc 728350a2 wdmaud!CWorker::_DoSingleJobs+0x44 1c 32f1f8f4 728380f3 wdmaud!CWorker::_ThreadProc+0x23c 1d 32f1f908 75903677 wdmaud!CWorker::_StaticThreadProc+0x2e 1e 32f1f914 77d59f02 kernel32!BaseThreadInitThunk+0xe 1f 32f1f954 77d59ed5 ntdll!__RtlUserThreadStart+0x70

derekbruening commented 9 years ago

From rnk@google.com on November 17, 2011 10:50:50

Just some notes as I investigate these.

The RtlMemoryZone functions implement a simple pool allocator that doesn't grow or resize. You can allocate from it until you hit the next page boundary beyond your request size, and you can reset it and allocate some more from it. It also has locks that you can use with multiple threads to negotiate access. It is *not considered a heap according to RtlGetProcessHeaps, so I think we can ignore it.

Rtl*MemoryBlockLookaside behaves very similarly, but it seems to have sized headers, and the blocks are allocated in space separate from the returned handle. I also believe you can allocate more virtual memory off the end of it via RtlExtendMemoryBlockLookaside. I don't understand this set of routines as well, but none of the addresses it gives me back are considered to be inside any heap listed by RtlGetProcessHeaps. Reset also doesn't seem to work, so I may not be using the API correctly. IMO this needs more investigation, and I should add some strace-like instrumentation in DrMemory for the arguments and return values of these routines, so we can see if these addresses get passed to other heap routines.

My experience if I ignore both of these routines in DrM right now and try to run media_unittests AudioOutput* is that I end up somewhere near here:

ChildEBP RetAddr

00 1fb58e70 6533fddc ntdll!ZwRaiseHardError+0x12 01 1fb58ec0 65312e8d dynamorio!nt_messagebox+0xec [c:\src\dynamorio\core\win32\ntdll.c @ 3294] 02 1fb58ee8 651d4d86 dynamorio!debugbox+0x4d [c:\src\dynamorio\core\win32\os.c @ 3436] 03 1fb59468 653085c4 dynamorio!notify+0x1a6 [c:\src\dynamorio\core\utils.c @ 1866] 04 1fb5949c 10023da1 dynamorio!dr_fragment_app_pc+0x1c4 [c:\src\dynamorio\core\x86\instrument.c @ 5001] 05 1fb59994 100090c2 drmemorylib!instrument_bb+0x7c1 [c:\src\drmemory\drmemory\readwrite.c @ 3445] 06 1fb59a90 653008fd drmemorylib!event_basic_block+0x582 [c:\src\drmemory\drmemory\drmemory.c @ 479] 07 1fb59b00 652cc355 dynamorio!instrument_basic_block+0x2ad [c:\src\dynamorio\core\x86\instrument.c @ 1300] 08 1fb59ba4 652c39c3 dynamorio!client_process_bb+0x65 [c:\src\dynamorio\core\x86\interp.c @ 2392] 09 1fb59dfc 652ce6d8 dynamorio!build_bb_ilist+0x29e3 [c:\src\dynamorio\core\x86\interp.c @ 3295] 0a 1fb59f40 651bb45f dynamorio!build_basic_block_fragment+0x2e8 [c:\src\dynamorio\core\x86\interp.c @ 4209] 0b 1fb59ff4 1fb0210e dynamorio!dispatch+0x7cf [c:\src\dynamorio\core\dispatch.c @ 189] WARNING: Frame IP not in any known module. Following frames may be wrong. 0c 0037f18c 75d4e55f 0x1fb0210e 0d 0037f1dc 73e07442 kernel32!GlobalReAlloc+0x17f 0e 0037f1fc 73e076d9 WINMM!InternalLoadDriver+0x7f 0f 0037f330 73e0768a WINMM!InternalOpenDriver+0x34 10 0037f348 73e0762f WINMM!DrvOpen+0x54 11 0037f5bc 73e08907 WINMM!mmDrvOpen+0x3e 12 0037f5dc 73e08858 WINMM!MidiInit+0x34 13 0037f5ec 73e0874f WINMM!InitDevices+0xc5

The missing frame inside GlobalReAlloc looks like RtlReAllocateHeap:

0:000> u 75d4e55f - 6 kernel32!GlobalReAlloc+0x179: 75d4e559 ff156003d375 call dword ptr [kernel32!_imp__RtlReAllocateHeap (75d30360)] 75d4e55f 8bf8 mov edi,eax 75d4e561 85ff test edi,edi 75d4e563 0f8414480000 je kernel32!GlobalReAlloc+0x195 (75d52d7d) 75d4e569 893b mov [ebx],edi 75d4e56b 0fb706 movzx eax,word ptr [esi] 75d4e56e 83e0f7 and eax,0xfffffff7 75d4e571 668906 mov [esi],ax

Which means we're actually interpreting client code from alloc_unopt.c. I get a syslog warning about the PC being from the client earlier, so this makes sense.

If I continue from here, I end up with a crash while trying to execute from NULL. I think what happens is that we return NULL from the realloc routine, as the XXX comments say in replace_realloc_template_Rtl. It could be issue #71 .

It needs more investigation to figure out if these issues are separate or if the app is attempting to call RtlReAllocateHeap on memory allocated from the Rtl_MemoryZone or Rtl_BlockLookaside routines.

For now we should disable these tests in media_unittests, and also investigate why the bot isn't hitting these.

Owner: rnk@google.com

derekbruening commented 9 years ago

From rnk@google.com on November 17, 2011 13:05:59

The bot isn't hitting these because the tests are disabled when running headless or if there's no audio output device. :)

We should add AudioOutputControllerTest.* to the exclusions until this issue is fixed.

derekbruening commented 9 years ago

From rnk@google.com on November 30, 2011 14:47:42

This issue was closed by revision r641 .

Status: Fixed

derekbruening commented 9 years ago

From bruen...@google.com on November 30, 2011 17:12:11

Re-opening for actually handling these. The right solution is to track these allocations like all other heap allocations. r641 simply disables the fatal warning about them being unhandled, b/c we suspect they are only used by system libraries and haven't seen any interfaces exposed through documented APIs, making them lower priority.

Status: Accepted
Owner: ---
Labels: -Priority-Medium Priority-Low