나는 정상 페이지 힙 (가득 차 있지 않음)로 크래시 시나리오 (고립 된 테스트 응용 프로그램에서)를 테스트하려고한다.페이지 힙은 유용한 스택 정보를 기록하지 않습니다?
내가
gflags /p /enable Test.exe
와 플래그를 설정하고 난 하나 개의 요소
...
const size_t s = 100;
vector<int> v1(s, 0);
int* v1_base = &v1[0];
write_to_memory_int(v1_base, s+1);
...
실제로 블록이 벡터 디부 토르에서 해제하여 정수 버퍼를 덮어있어, 나는 휴식을 취한다. 휴식의 호출 스택이 제대로보고 : 나는 오류있는 할당 볼 때
0:005> kp
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr
0785faa4 11229df2 verifier!VerifierStopMessage+0x1f8
0785fb08 1122a22a verifier!AVrfpDphReportCorruptedBlock+0x1c2
0785fb64 1122a742 verifier!AVrfpDphCheckNormalHeapBlock+0x11a
0785fb84 112290d3 verifier!AVrfpDphNormalHeapFree+0x22
0785fba8 77951564 verifier!AVrfDebugPageHeapFree+0xe3
0785fbf0 7790ac29 ntdll!RtlDebugFreeHeap+0x2f
0785fce4 778b34a2 ntdll!RtlpFreeHeap+0x5d
0785fd04 750c14dd ntdll!RtlFreeHeap+0x142
0785fd18 71fc4c39 kernel32!HeapFree+0x14
0785fd64 00404b0a msvcr80!free(void * pBlock = 0x0726f7b8)+0xcd [f:\dd\vctools\crt_bld\self_x86\crt\src\free.c @ 110]
0785fd90 00402ac7 Test!std::vector<int,std::allocator<int> >::_Tidy
...
그러나, 나는 단지 받기 :
입니다0:005> !heap -p -a 0x0726f7b8
address 0726f7b8 found in
_HEAP @ 30000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0726f790 0039 0000 [00] 0726f7b8 00190 - (busy)
1122a6a7 verifier!AVrfpDphNormalHeapAllocate+0x000000d7
11228f6e verifier!AVrfDebugPageHeapAllocate+0x0000030e
77950d96 ntdll!RtlDebugAllocateHeap+0x00000030
7790af0d ntdll!RtlpAllocateHeap+0x000000c4
778b3cfe ntdll!RtlAllocateHeap+0x0000023a
, 할당 스택 추적이 입니다, 그러나 그것은 완전히 쓸데없는 RtlAllocateHeap
에 멈춘다.
메모리에 스택 추적을 보면 :
dt _DPH_BLOCK_INFORMATION ....-0x20
=>
0:005> dds 0x03e556f4
03e556f4 00000000
03e556f8 00002050
03e556fc 00050000
03e55700 1122a6a7 verifier!AVrfpDphNormalHeapAllocate+0xd7
03e55704 11228f6e verifier!AVrfDebugPageHeapAllocate+0x30e
03e55708 77950d96 ntdll!RtlDebugAllocateHeap+0x30
03e5570c 7790af0d ntdll!RtlpAllocateHeap+0xc4
03e55710 778b3cfe ntdll!RtlAllocateHeap+0x23a
03e55714 00000000
03e55718 00003001
03e5571c 0004005e
이 더 기록 된 사실 아무것도 존재하지 않은 것 같습니다.
유용한 스택 추적을 기록하기 위해 페이지 힙을 수정하려면 어떻게해야합니까?
테스트 프로젝트는 이 아니며 FPO (/ Oy)로 컴파일 된이 아니므로 RtlAllocateHeap
은 FPO의 영향을 받겠습니까?
업데이트 : (아래 참조)는 VC80 (VS2005) 런타임 libs와 모두 malloc
뿐만 아니라 op new
가지고있는 것으로 생각된다 수동으로 할당에 스테핑에 의해 문제의 호출의 FPO 다움을 확인 어떤 형태의 FPO가 가능 해지면 페이지 힙의 스택 DB에 대한 스택 추적을 엉망으로 만들 수 있습니다. 내가 진짜 할당 스택 트레이스를 체크 아웃해야한다 코멘트에 지적 @Marc 셔먼에
0:004> kv
ChildEBP RetAddr Args to Child
077efa7c 77c8af0d 05290000 01001002 00000190 ntdll!RtlDebugAllocateHeap+0x16 (FPO: [Non-Fpo])
077efb60 77c33cfe 00000190 00000000 00000000 ntdll!RtlpAllocateHeap+0xc4 (FPO: [Non-Fpo])
077efbe4 72344d83 05290000 01001002 00000190 ntdll!RtlAllocateHeap+0x23a (FPO: [Non-Fpo])
077efc04 62f595ee 00000190 00000000 00000000 MSVCR80!malloc+0x7a (FPO: [1,0,0]) (CONV: cdecl)
077efc1c 00406a44 00000190 ebecf74f 00000001 MFC80U!operator new+0x2f (FPO: [Uses EBP] [1,0,0]) (CONV: cdecl)
077efc48 00405479 00000064 00000000 3fffffff Test!std::_Allocate<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >+0x84 (FPO: [Non-Fpo]) (CONV: cdecl)
077efcb8 004049f4 00000064 ebecf68f 00000000 Test!std::vector<unsigned int,std::allocator<unsigned int> >::_Buy+0x69 (FPO: [Non-Fpo]) (CONV: thiscall)
077efd88 00402a4f 00000064 077efdc0 ebecf44b Test!std::vector<int,std::allocator<int> >::_Construct_n+0x44 (FPO: [Non-Fpo]) (CONV: thiscall)
077eff4c 72342848 00000000 ebec8474 00000000 Test!crashFN+0x35f (FPO: [Non-Fpo]) (CONV: cdecl)
077eff84 723428c8 75da33aa 072ab3d8 077effd4 MSVCR80!_callthreadstart+0x1b (FPO: [Non-Fpo]) (CONV: cdecl)
077eff88 75da33aa 072ab3d8 077effd4 77c39f72 MSVCR80!_threadstart+0x5a (FPO: [1,0,0]) (CONV: stdcall)
077eff94 77c39f72 072ab3d8 70fca8b2 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
077effd4 77c39f45 7234286e 072ab3d8 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
077effec 00000000 7234286e 072ab3d8 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
는 아마 C++ 런타임 및/또는 CRT는 FPO 컴파일됩니다. 'dds 0x03e556f4 L80'으로 dds의 범위를 늘리면 어떨까요? 흥미로운 반송 주소가 보이십니까? –
@Marc : 아니요, 첫 번째 stac (흥미 롭거나 관련이없는 스택)을 넘어 흥미로운 부분이없는 것처럼 보입니다. –
게시 한 메모리의 해당 스택 추적에 관한 이상한 점은 해당 반환 주소가 서로 즉시 이어지는 것입니다. 일반적으로 저장된 EBP가 중간에 표시됩니다. 처음에 0x03e556f4 값을 어떻게 찾았습니까? –