Changeset 914 for trunk/xcache.c


Ignore:
Timestamp:
2012-06-21T11:44:18+02:00 (2 years ago)
Author:
moo
Message:

crash dump support for windows

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/xcache.c

    r903 r914  
    33363336/* }}} */ 
    33373337 
     3338#ifdef ZEND_WIN32 
     3339#include "dbghelp.h" 
     3340typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, 
     3341        CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
     3342        CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
     3343        CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam 
     3344        ); 
     3345 
     3346static PTOP_LEVEL_EXCEPTION_FILTER oldFilter; 
     3347static HMODULE dbghelpModule = NULL; 
     3348static char crash_dumpPath[_MAX_PATH]; 
     3349static MINIDUMPWRITEDUMP dbghelp_MiniDumpWriteDump; 
     3350 
     3351static LONG WINAPI miniDumperFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) /* {{{ */ 
     3352{ 
     3353    HANDLE fileHandle; 
     3354 
     3355    SetUnhandledExceptionFilter(oldFilter); 
     3356 
     3357    /* create the file */ 
     3358    fileHandle = CreateFile(crash_dumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
     3359 
     3360    if (fileHandle != INVALID_HANDLE_VALUE) { 
     3361        MINIDUMP_EXCEPTION_INFORMATION exceptionInformation; 
     3362        BOOL ok; 
     3363 
     3364        exceptionInformation.ThreadId = GetCurrentThreadId(); 
     3365        exceptionInformation.ExceptionPointers = pExceptionInfo; 
     3366        exceptionInformation.ClientPointers = FALSE; 
     3367 
     3368        /* write the dump */ 
     3369        ok = dbghelp_MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpNormal, &exceptionInformation, NULL, NULL); 
     3370        CloseHandle(fileHandle); 
     3371        if (ok) { 
     3372            zend_error(E_ERROR, "Saved dump file to '%s'", crash_dumpPath); 
     3373            return EXCEPTION_EXECUTE_HANDLER; 
     3374        } 
     3375        else { 
     3376            zend_error(E_ERROR, "Failed to save dump file to '%s' (error %d)", crash_dumpPath, GetLastError()); 
     3377        } 
     3378    } 
     3379    else { 
     3380        zend_error(E_ERROR, "Failed to create dump file '%s' (error %d)", crash_dumpPath, GetLastError()); 
     3381    } 
     3382 
     3383    return EXCEPTION_CONTINUE_SEARCH; 
     3384} 
     3385/* }}} */ 
     3386 
     3387static void xcache_restore_crash_handler() /* {{{ */ 
     3388{ 
     3389    if (oldFilter) { 
     3390        SetUnhandledExceptionFilter(oldFilter); 
     3391        oldFilter = NULL; 
     3392    } 
     3393} 
     3394/* }}} */ 
     3395static void xcache_init_crash_handler() /* {{{ */ 
     3396{ 
     3397    /* firstly see if dbghelp.dll is around and has the function we need 
     3398       look next to the EXE first, as the one in System32 might be old 
     3399       (e.g. Windows 2000) */ 
     3400    char dbghelpPath[_MAX_PATH]; 
     3401 
     3402    if (GetModuleFileName(NULL, dbghelpPath, _MAX_PATH)) { 
     3403        char *slash = strchr(dbghelpPath, '\\'); 
     3404        if (slash) { 
     3405            strcpy(slash + 1, "DBGHELP.DLL"); 
     3406            dbghelpModule = LoadLibrary(dbghelpPath); 
     3407        } 
     3408    } 
     3409 
     3410    if (!dbghelpModule) { 
     3411        /* load any version we can */ 
     3412        dbghelpModule = LoadLibrary("DBGHELP.DLL"); 
     3413        if (!dbghelpModule) { 
     3414            zend_error(E_ERROR, "Unable to enable crash dump saver: %s", "DBGHELP.DLL not found"); 
     3415            return; 
     3416        } 
     3417    } 
     3418 
     3419    dbghelp_MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dbghelpModule, "MiniDumpWriteDump"); 
     3420    if (dbghelp_MiniDumpWriteDump) { 
     3421        zend_error(E_ERROR, "Unable to enable crash dump saver: %s", "DBGHELP.DLL too old"); 
     3422        return; 
     3423    } 
     3424 
     3425    /* work out a good place for the dump file */ 
     3426    { 
     3427        char tmpPath[_MAX_PATH]; 
     3428        if (!GetTempPath(_MAX_PATH, tmpPath)) { 
     3429            strcpy(tmpPath, "c:\\temp"); 
     3430        } 
     3431        sprintf(crash_dumpPath, "%s\\php-%s-xcache-%s-%lu.dmp", PHP_VERSION, XCACHE_VERSION, (unsigned long) GetCurrentProcessId()); 
     3432    } 
     3433 
     3434    oldFilter = SetUnhandledExceptionFilter(&miniDumperFilter); 
     3435} 
     3436/* }}} */ 
     3437#else 
    33383438/* old signal handlers {{{ */ 
    33393439typedef void (*xc_sighandler_t)(int); 
     
    33433443/* }}} */ 
    33443444static void xcache_signal_handler(int sig); 
    3345 static void xcache_restore_signal_handler() /* {{{ */ 
     3445static void xcache_restore_crash_handler() /* {{{ */ 
    33463446{ 
    33473447#define FOREACH_SIG(sig) do { \ 
     
    33573457} 
    33583458/* }}} */ 
    3359 static void xcache_init_signal_handler() /* {{{ */ 
     3459static void xcache_init_crash_handler() /* {{{ */ 
    33603460{ 
    33613461#define FOREACH_SIG(sig) \ 
     
    33673467static void xcache_signal_handler(int sig) /* {{{ */ 
    33683468{ 
    3369     xcache_restore_signal_handler(); 
     3469    xcache_restore_crash_handler(); 
    33703470    if (xc_coredump_dir && xc_coredump_dir[0]) { 
    33713471        if (chdir(xc_coredump_dir) != 0) { 
     
    33773477} 
    33783478/* }}} */ 
     3479#endif 
    33793480 
    33803481/* {{{ PHP_INI */ 
     
    37123813 
    37133814    if (xc_coredump_dir && xc_coredump_dir[0]) { 
    3714         xcache_init_signal_handler(); 
     3815        xcache_init_crash_handler(); 
    37153816    } 
    37163817 
     
    37673868 
    37683869    if (xc_coredump_dir && xc_coredump_dir[0]) { 
    3769         xcache_restore_signal_handler(); 
     3870        xcache_restore_crash_handler(); 
    37703871    } 
    37713872    if (xc_coredump_dir) { 
Note: See TracChangeset for help on using the changeset viewer.