/* ==================================================================== * Copyright (c) 2003-2006, Martin Hauner * http://subcommander.tigris.org * * Subcommander is licensed as described in the file doc/COPYING, which * you should have received as part of this distribution. * ==================================================================== */ // sc #include "Stacktrace.h" #include "StackWalk.h" #include "StdException.h" #include "util/apr.h" // apr #include #include #include // sys #include #include #include // exception handler void __cdecl handleException( unsigned int e, EXCEPTION_POINTERS* pExp ) { sc::String dump( "no dump" ); if( true/*Stacktrace::getDump()*/ ) { apr::Pool pool; apr_time_t now = apr_time_now(); char* nowstr = apr_psprintf( pool, "%" APR_TIME_T_FMT, now ); const char* tempdir = 0; apr_status_t status = apr_temp_dir_get( &tempdir, pool ); char* tempout = apr_pstrcat( pool, tempdir, "\\sc-", nowstr, ".dmp", 0 ); HANDLE file = CreateFile( tempout, FILE_ALL_ACCESS, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ); if( file != INVALID_HANDLE_VALUE ) { MINIDUMP_EXCEPTION_INFORMATION mee; mee.ThreadId = GetCurrentThreadId(); mee.ExceptionPointers = pExp; mee.ClientPointers = TRUE; BOOL success = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), file, (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithoutOptionalData | MiniDumpWithProcessThreadData), &mee, 0, 0 ); // get a clean path without ~ parts. char buf[1025] = {}; GetLongPathName( tempout, buf, 1024 ); dump = buf; CloseHandle(file); } } Stackwalk stack(pExp); stack.walk(); throw StdException(e,stack.getFrames(),dump); } // member bool Stacktrace::_dump = false; void Stacktrace::setupProcess() { SymSetOptions( SYMOPT_IGNORE_NT_SYMPATH | SYMOPT_AUTO_PUBLICS | SYMOPT_CASE_INSENSITIVE | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME ); if( ! SymInitialize( GetCurrentProcess(),0,true) ) { // error handling? } setupThread(); } void Stacktrace::shutdownProcess() { if( ! SymCleanup(GetCurrentProcess()) ) { // error handling? } shutdownThread(); } void Stacktrace::setupThread() { _set_se_translator(handleException); } void Stacktrace::shutdownThread() { _set_se_translator(0); } void Stacktrace::setDump( bool dump ) { _dump = dump; } bool Stacktrace::getDump() { return _dump; }