可以在win32用户应用程序中捕获未处理的异常吗? (setunhandledexceptionfilter())

时间:2013-12-19 06:16:20

标签: windows winapi unhandled-exception

我花了很多时间在我的进程(win32)中使用所谓的setunhandledexceptionfilter()来捕获未处理的异常。

但是当WER(Windows错误报告 - DR.watson众所周知)显示时,我没有捕获异常。

在我的APP中没有第三方的情况下无法捕捉所有异常情况吗?

我认为有处理方法,但我不明白。

我不习惯Windows DEV环境。这就是为什么我在谷歌搜索中失去了精神。

以下是我在vc110(Visual Studio 2012)中的测试用例。

chat test[65];
int main() { 
 // after attaching unhandled exception call-back using setunhandledexceptionfilter()
 // die point (ACCESS_VIOLATION c0000005)
 for (int k=0; k<1000000; k++) 
     test[k]=65;

在WER(Windows错误报告)发生后未调用我的回调。它不能像我的意图那样工作。 * strcpy(NULL, "TEST")没关系(成功) *

以下是我的源代码。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <assert.h>
#include <process.h>
#include <direct.h>
#include <conio.h>
#include <time.h>
#include <Windows.h>

#include <tchar.h>
#include <dbghelp.h>
#include <stdio.h>
#include <crtdbg.h>
#include <WinBase.h>
#pragma comment ( lib, "dbghelp.lib" )


void CreateMiniDump( EXCEPTION_POINTERS* pep ); 
BOOL CALLBACK MyMiniDumpCallback(
    PVOID                            pParam, 
    const PMINIDUMP_CALLBACK_INPUT   pInput, 
    PMINIDUMP_CALLBACK_OUTPUT        pOutput 
); 

///////////////////////////////////////////////////////////////////////////////
// Minidump creation function 
//

#if 0
LONG WINAPI lpTopLevelExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo);
#endif

void CreateMiniDump( EXCEPTION_POINTERS* pep ) 
{
    time_t t;
    struct tm *tinfo;
    wchar_t dump_name[128];
    HANDLE hFile;
    time(&t);
    tinfo = localtime(&t);

    wcsftime(dump_name, 128, L"MiniDump[%Y%m%d][%H_%M_%S].dmp", tinfo);

    // file format MiniDump[YYYYMMDD][HH_MM_SEC]
    hFile = CreateFile(dump_name, GENERIC_READ | GENERIC_WRITE, 
        0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 

    if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) ) 
    {
        // Create the minidump 

        MINIDUMP_EXCEPTION_INFORMATION mdei; 
        MINIDUMP_CALLBACK_INFORMATION mci; 
        MINIDUMP_TYPE mdt;
        BOOL rv;

        mdei.ThreadId           = GetCurrentThreadId(); 
        mdei.ExceptionPointers  = pep; 
        mdei.ClientPointers     = FALSE; 



        mci.CallbackRoutine     = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback; 
        mci.CallbackParam       = 0; 

        mdt       = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory| MiniDumpWithThreadInfo); 

        rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), 
            hFile, mdt, (pep != 0) ? &mdei : 0, 0, &mci ); 

        if( !rv ) 
            _tprintf( _T("MiniDumpWriteDump failed. Error: %u \n"), GetLastError() ); 
        else 
            _tprintf( _T("Minidump created.\n") ); 

        // Close the file 

        CloseHandle( hFile ); 

    }
    else 
    {
        _tprintf( _T("CreateFile failed. Error: %u \n"), GetLastError() ); 
    }

}


///////////////////////////////////////////////////////////////////////////////
// Custom minidump callback 
//

BOOL CALLBACK MyMiniDumpCallback(
    PVOID                            pParam, 
    const PMINIDUMP_CALLBACK_INPUT   pInput, 
    PMINIDUMP_CALLBACK_OUTPUT        pOutput 
) 
{
    BOOL bRet = FALSE; 


    // Check parameters 

    if( pInput == 0 ) 
        return FALSE; 

    if( pOutput == 0 ) 
        return FALSE; 


    // Process the callbacks 

    switch( pInput->CallbackType ) 
    {
        case IncludeModuleCallback: 
        {
            // Include the module into the dump 
            bRet = TRUE; 
        }
        break; 

        case IncludeThreadCallback: 
        {
            // Include the thread into the dump 
            bRet = TRUE; 
        }
        break; 

        case ModuleCallback: 
        {
            // Does the module have ModuleReferencedByMemory flag set ? 

            if( !(pOutput->ModuleWriteFlags & ModuleReferencedByMemory) ) 
            {
                // No, it does not - exclude it 

                wprintf( L"Excluding module: %s \n", pInput->Module.FullPath ); 

                pOutput->ModuleWriteFlags &= (~ModuleWriteModule); 
            }

            bRet = TRUE; 
        }
        break; 

        case ThreadCallback: 
        {
            // Include all thread information into the minidump 
            bRet = TRUE;  
        }
        break; 

        case ThreadExCallback: 
        {
            // Include this information 
            bRet = TRUE;  
        }
        break; 

        case MemoryCallback: 
        {
            // We do not include any information here -> return FALSE 
            bRet = FALSE; 
        }
        break; 

        case CancelCallback: 
            break; 
    }

    return bRet; 

}

LONG WINAPI exception_filter_func(EXCEPTION_POINTERS* pep)
{
    if (pep == NULL) {
        return EXCEPTION_EXECUTE_HANDLER;
    }

    if (pep->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateMiniDump, pep, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    } else {
        CreateMiniDump(pep);
    }

    return EXCEPTION_EXECUTE_HANDLER;
}
char test[65];

int main(int argc, char **argv)
{
    int k;
    SetUnhandledExceptionFilter(exception_filter_func);
    // exception occured (ACCESS_VIOLATION)
    for (k=0; k<1000000; k++) 
      test[k]=65;
}

0 个答案:

没有答案