在访问冲突时创建转储文件

时间:2012-12-14 09:50:23

标签: c++ .net c debugging

我想在发生无法处理的访问冲突时创建进程转储文件。

目前,我已经注册了我的,未处理的异常回调:

SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);

CustomUnhandledExceptionFilter创建转储文件并打印调用堆栈。

但是这种方法有一个缺陷 - 它已经在AV已经发生时完成,AV异常被抛出并且没有被它发生的线程处理。当异常即将离开线程范围和转储创建时调用未处理的异常回调此时没有函数的局部变量,因为堆栈指针丢失,异常发生。

有没有办法克服这个问题?我想看看在AV发生的那一刻获得AV的线程堆栈。

3 个答案:

答案 0 :(得分:7)

VS

#include "stdafx.h"
#include <windows.h>
#include <dbghelp.h>

LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
{
    HANDLE hFile = CreateFile(
                L"proc.dmp",
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL
            );
    MINIDUMP_EXCEPTION_INFORMATION mei;
    mei.ThreadId = GetCurrentThreadId();
    mei.ClientPointers = TRUE;
    mei.ExceptionPointers = ExceptionInfo;
    MiniDumpWriteDump(
        GetCurrentProcess(), 
        GetCurrentProcessId(), 
        hFile, 
        MiniDumpNormal,
        &mei,
        NULL,
        NULL);

    return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
    int* p = NULL;
    *p = 1;
    return 0;
}

WinDbg的

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.


Loading Dump File [D:\Documents\Visual Studio 2012\Projects\Test\Debug\proc.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available

Symbol search path is: SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows 7 Version 7600 UP Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Sat Dec 15 19:29:31.000 2012 (UTC + 4:00)
System Uptime: not available
Process Uptime: not available
......................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(8d8.1084): Access violation - code c0000005 (first/second chance not available)
eax=fffffffd ebx=005d0d78 ecx=0022f070 edx=778964f4 esi=005d0d38 edi=0022f110
eip=778964f4 esp=0022edd0 ebp=0022ede0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
778964f4 c3              ret
0:000> .ecxr
eax=00000000 ebx=7ffdf000 ecx=0022fa30 edx=778964f4 esi=0022fcf4 edi=0022fdcc
eip=0124157c esp=0022fcf4 ebp=0022fdcc iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
*** WARNING: Unable to verify checksum for dump.exe
dump!wmain+0x3c:
0124157c c70001000000    mov     dword ptr [eax],1    ds:0023:00000000=????????
0:000> dv
           argc = 0n1
           argv = 0x00280e38
           p = 0x00000000
0:000> kb
  *** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr  Args to Child              
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> u .
dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]:
0124157c c70001000000    mov     dword ptr [eax],1
01241582 33c0            xor     eax,eax
01241584 5f              pop     edi
01241585 5e              pop     esi
01241586 5b              pop     ebx
01241587 81c4cc000000    add     esp,0CCh
0124158d 3bec            cmp     ebp,esp
0124158f e8c0fbffff      call    dump!ILT+335(__RTC_CheckEsp) (01241154)
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

GetPageUrlData failed, server returned HTTP status 404
URL requested: http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1

FAULTING_IP: 
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0124157c c70001000000    mov     dword ptr [eax],1

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 0124157c (dump!wmain+0x0000003c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00000000
Attempt to write to address 00000000

DEFAULT_BUCKET_ID:  NULL_POINTER_WRITE

PROCESS_NAME:  dump.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1:  00000001

EXCEPTION_PARAMETER2:  00000000

WRITE_ADDRESS:  00000000 

FOLLOWUP_IP: 
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0124157c c70001000000    mov     dword ptr [eax],1

MOD_LIST: <ANALYSIS/>

FAULTING_THREAD:  00001084

PRIMARY_PROBLEM_CLASS:  NULL_POINTER_WRITE

BUGCHECK_STR:  APPLICATION_FAULT_NULL_POINTER_WRITE

LAST_CONTROL_TRANSFER:  from 01241b19 to 0124157c

STACK_TEXT:  
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  ~0s; .ecxr ; kb

FAULTING_SOURCE_CODE:  
    31: int _tmain(int argc, _TCHAR* argv[])
    32: {
    33:     SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
    34:     int* p = NULL;
>   35:     *p = 1;
    36:     return 0;
    37: }
    38: 


SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  dump!wmain+3c

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: dump

IMAGE_NAME:  dump.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  50cc9743

FAILURE_BUCKET_ID:  NULL_POINTER_WRITE_c0000005_dump.exe!wmain

BUCKET_ID:  APPLICATION_FAULT_NULL_POINTER_WRITE_dump!wmain+3c

WATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1

Followup: MachineOwner
---------

答案 1 :(得分:1)

尝试使用AddVectoredExceptionHandler。异常时刻的线程上下文作为参数传递给此方法的回调proc。

答案 2 :(得分:1)

为了保持异常上下文不变,您可以从外部进程创建minidump,该进程使用DebugActiveProcess API调试感兴趣的进程,并在调试过程中接收异常事件。在使用ContinueDebugEvent释放debugee之前创建Minidump会保留调用堆栈和异常上下文。