/* ====================================================================
* 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 <apr_time.h>
#include <apr_strings.h>
#include <apr_file_io.h>
// sys
#include <windows.h>
#include <eh.h>
#include <dbghelp.h>
// 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;
}
syntax highlighted by Code2HTML, v. 0.9.1