void test_passthru() { PFV unex; unex = set_unexpected( throw_int ); try { passthru(); } catch( int ) { printf( "passthru ok\n" ); } set_unexpected( unex ); }
void crash_handler::set_thread_exception_handlers() { if (!is_crash_handle_enabled()) return; // Catch terminate() calls. // In a multithreaded environment, terminate functions are maintained // separately for each thread. Each new thread needs to install its own // terminate function. Thus, each thread is in charge of its own termination handling. // http://msdn.microsoft.com/en-us/library/t6fk7h29.aspx // NOTE : turn off terminate handle // set_terminate(terminate_handler); // Catch unexpected() calls. // In a multithreaded environment, unexpected functions are maintained // separately for each thread. Each new thread needs to install its own // unexpected function. Thus, each thread is in charge of its own unexpected handling. // http://msdn.microsoft.com/en-us/library/h46t5b69.aspx set_unexpected(unexpected_handler); // Catch a floating point error typedef void (*sigh)(int); signal(SIGFPE, (sigh)sigfpe_handler); // Catch an illegal instruction signal(SIGILL, sigill_handler); // Catch illegal storage access errors signal(SIGSEGV, sigsegv_handler); }
int main() { printf( "EXCOK: start\n" ); set_terminate( &no_handler ); test_basics(); test_scalars(); init_class(); test_class(); test_cl_ptrs(); test_passthru(); test_rethrow(); try { ++throws; set_unexpected( &unexp ); test_unexpected(); } catch( long l ) { ++catches; if( l != 675L ) { printf( "unexpected failure %l\n", l ); } } if( throws != catches ) { printf( "catches != throws\n" ); } set_terminate( &my_term ); test_term(); printf( "terminate did not abort\n" ); return( 0 ); }
void CCrashHandler::SetThreadExceptionHandlers() { // Catch terminate() calls. // In a multithreaded environment, terminate functions are maintained // separately for each thread. Each new thread needs to install its own // terminate function. Thus, each thread is in charge of its own termination handling. // http://msdn.microsoft.com/en-us/library/t6fk7h29.aspx set_terminate(TerminateHandler); // Catch unexpected() calls. // In a multithreaded environment, unexpected functions are maintained // separately for each thread. Each new thread needs to install its own // unexpected function. Thus, each thread is in charge of its own unexpected handling. // http://msdn.microsoft.com/en-us/library/h46t5b69.aspx set_unexpected(UnexpectedHandler); // Catch a floating point error typedef void (*sigh)(int); signal(SIGFPE, (sigh)SigfpeHandler); // Catch an illegal instruction signal(SIGILL, SigillHandler); // Catch illegal storage access errors signal(SIGSEGV, SigsegvHandler); }
void set_thread_exception_handlers() { set_terminate(handle_terminate); set_unexpected(handle_unexpected); signal(SIGABRT, handle_signal); signal(SIGFPE, handle_signal); signal(SIGILL, handle_signal); signal(SIGSEGV, handle_signal); }
int main (int argc, char *argv[]) { if (argc > 1) { unexpected_handler save = set_unexpected (handler); return save == handler; } return 0; }
void i4_main(w32 argc, i4_const_str * argv) { #ifdef _WINDOWS set_unexpected(myUnexpectedExit); #endif //golgotha_app app(argc, argv); g1_app=new golgotha_app(argc,argv); g1_app->run(); #ifdef _WINDOWS cwnd.Detach(); //Detach the MFC from the Main-Window, we are clearing up manually #endif delete g1_app; g1_app=NULL; }
int CCrashHandler::UnSetThreadExceptionHandlers() { crSetErrorMsg(_T("Unspecified error.")); DWORD dwThreadId = GetCurrentThreadId(); CAutoLock lock(&m_csThreadExceptionHandlers); std::map<DWORD, ThreadExceptionHandlers>::iterator it = m_ThreadExceptionHandlers.find(dwThreadId); if(it==m_ThreadExceptionHandlers.end()) { // No exception handlers were installed for the caller thread? ATLASSERT(0); crSetErrorMsg(_T("Crash handler wasn't previously installed for current thread.")); return 1; } ThreadExceptionHandlers* handlers = &(it->second); if(handlers->m_prevTerm!=NULL) set_terminate(handlers->m_prevTerm); if(handlers->m_prevUnexp!=NULL) set_unexpected(handlers->m_prevUnexp); if(handlers->m_prevSigFPE!=NULL) signal(SIGFPE, handlers->m_prevSigFPE); if(handlers->m_prevSigILL!=NULL) signal(SIGINT, handlers->m_prevSigILL); if(handlers->m_prevSigSEGV!=NULL) signal(SIGSEGV, handlers->m_prevSigSEGV); // Remove from the list m_ThreadExceptionHandlers.erase(it); // OK. crSetErrorMsg(_T("Success.")); return 0; }
void InstallCrashHandler(const WCHAR *crashDumpPath, const WCHAR *symDir) { assert(!gDumpEvent && !gDumpThread); if (!crashDumpPath) return; if (!StoreCrashDumpPaths(symDir)) return; if (!BuildSymbolPath()) return; // don't bother sending crash reports when running under Wine // as they're not helpful bool isWine= BuildModulesInfo(); if (isWine) return; BuildSystemInfo(); // at this point list of modules should be complete (except // dbghlp.dll which shouldn't be loaded yet) gExeType = DetectExeType(); // we pre-allocate as much as possible to minimize allocations // when crash handler is invoked. It's ok to use standard // allocation functions here. gCrashHandlerAllocator = new CrashHandlerAllocator(); gCrashDumpPath = str::Dup(crashDumpPath); gDumpEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (!gDumpEvent) return; gDumpThread = CreateThread(NULL, 0, CrashDumpThread, NULL, 0, 0); if (!gDumpThread) return; gPrevExceptionFilter = SetUnhandledExceptionFilter(DumpExceptionHandler); signal(SIGABRT, onSignalAbort); #if defined(_MSC_VER) // those are only in msvc? There is std::set_terminate() and // std::set_unexpected() in C++ in <exception> set_terminate(onTerminate); set_unexpected(onUnexpected); #endif }
void main() { int fd; set_unexpected(unexpected_routine); // This was added if ((fd = open("TERMS1.TXT", O_RDONLY | O_CREAT)) == -1 ) { cout<<"Unable to open file TERMS1.TXT"<<endl; return; } try { Vector vec1(4); for (int index = 0; index < 4; index++) vec1[index] = 4.0 * index; cout<<"Elements of vec1: "<<endl; vec1.Traverse(); Create_New_Vector(); } catch(char * err) { cout<<"Inside catch(char *) of main..."<<endl; cout<<err<<endl; } catch(Xception & err) { cout<<"Inside catch(Xception &) of main..."<<endl; err.Display(); } catch(...) { cout<<"Inside the catch all handler of main..."<<endl; } cout<<"Closing file descriptor..."<<endl; close(fd); cout<<"Exiting main - program completed..."<<'\n'; }
static void ssh_set_exceptionHandlers() { // установить фильтр исключений SetUnhandledExceptionFilter(Win32UnhandledExceptionFilter); // установить режимы отчета библиотеки времени выполнения //_CrtSetReportMode(_CRT_ERROR, 0); _CrtSetReportMode(_CRT_ASSERT, 0); set_terminate(ssh_terminate_handler); set_unexpected(ssh_unexp_handler); _set_purecall_handler(ssh_purecall_handler); _set_invalid_parameter_handler(ssh_invalid_parameter_handler); _set_new_handler(ssh_new_handler); // _set_security_error_handler(ssh_security_handler); signal(SIGABRT, ssh_signal_handler); signal(SIGINT, ssh_signal_handler); signal(SIGTERM, ssh_signal_handler); signal(SIGFPE, ssh_signal_handler); signal(SIGILL, ssh_signal_handler); signal(SIGSEGV, ssh_signal_handler); }
bool CrashHandlerWindows::registerThreadCrashHandlers() { Autolock autoLock(&m_Lock); DWORD dwThreadId = GetCurrentThreadId(); std::map<DWORD, ThreadExceptionHandlers>::iterator it = m_pPreviousCrashHandlers->m_threadExceptionHandlers.find(dwThreadId); if(it != m_pPreviousCrashHandlers->m_threadExceptionHandlers.end()) { LogWarning << "Crash handlers are already registered for this thread."; return false; } ThreadExceptionHandlers & threadHandlers = m_pPreviousCrashHandlers->m_threadExceptionHandlers[dwThreadId]; // Catch terminate() calls. // In a multithreaded environment, terminate functions are maintained // separately for each thread. Each new thread needs to install its own // terminate function. Thus, each thread is in charge of its own termination handling. // http://msdn.microsoft.com/en-us/library/t6fk7h29.aspx threadHandlers.m_terminateHandler = set_terminate(TerminateHandler); // Catch unexpected() calls. // In a multithreaded environment, unexpected functions are maintained // separately for each thread. Each new thread needs to install its own // unexpected function. Thus, each thread is in charge of its own unexpected handling. // http://msdn.microsoft.com/en-us/library/h46t5b69.aspx threadHandlers.m_unexpectedHandler = set_unexpected(UnexpectedHandler); // Catch a floating point error threadHandlers.m_SIGFPEHandler = signal(SIGFPE, (signal_handler)SIGFPEHandler); // Catch an illegal instruction threadHandlers.m_SIGILLHandler = signal(SIGILL, SignalHandler); // Catch illegal storage access errors threadHandlers.m_SIGSEGVHandler = signal(SIGSEGV, SignalHandler); return true; }
void CrashHandlerWindows::unregisterThreadCrashHandlers() { Autolock autoLock(&m_Lock); DWORD dwThreadId = GetCurrentThreadId(); std::map<DWORD, ThreadExceptionHandlers>::iterator it = m_pPreviousCrashHandlers->m_threadExceptionHandlers.find(dwThreadId); if(it == m_pPreviousCrashHandlers->m_threadExceptionHandlers.end()) { LogWarning << "Crash handlers were not registered for this thread."; return; } ThreadExceptionHandlers& threadHandlers = it->second; set_terminate(threadHandlers.m_terminateHandler); set_unexpected(threadHandlers.m_unexpectedHandler); signal(SIGFPE, threadHandlers.m_SIGFPEHandler); signal(SIGILL, threadHandlers.m_SIGILLHandler); signal(SIGSEGV, threadHandlers.m_SIGSEGVHandler); m_pPreviousCrashHandlers->m_threadExceptionHandlers.erase(it); }
InstallUnexpected::~InstallUnexpected() { set_unexpected(old); }
void _STLP_CALL unexpected() { unexpected_handler hdl; set_unexpected(hdl = set_unexpected((unexpected_handler)0)); hdl(); }
int __cdecl _tmain(int argc, const TCHAR* argv[], const TCHAR* envp[]) { int ret = 0; if (CheckEpoch()) return 1; cTWInit twInit; try { // set unexpected and terminate handlers // Note: we do this before Init() in case it attempts to call these handlers // TODO: move this into the Init() routine EXCEPTION_NAMESPACE set_terminate(tw_terminate_handler); EXCEPTION_NAMESPACE set_unexpected(tw_unexpected_handler); twInit.Init(argv[0]); TSS_Dependency(cTWAdmin); // set up the debug output cDebug::SetDebugLevel(cDebug::D_DEBUG); // first, get the right mode... TW_UNIQUE_PTR<iTWAMode> pMode(cTWAdminCmdLine::GetMode(argc, argv)); if (!pMode.get()) { // no valid mode passed; GetMode will display an appropriate string (include usage statement) ret = 1; goto exit; } // if version was requested, output version string and exit if (pMode.get()->GetModeID() == cTWAdminCmdLine::MODE_VERSION) { TCOUT << TSS_GetString(cTW, tw::STR_VERSION_LONG) << std::endl; ret = 0; goto exit; } // process the command line cCmdLineParser cmdLine; pMode->InitCmdLineParser(cmdLine); try { cmdLine.Parse(argc, argv); } catch (eError& e) { cTWUtil::PrintErrorMsg(e); TCERR << TSS_GetString(cTW, tw::STR_GET_HELP) << std::endl; ret = 1; goto exit; } // erase the command line // TODO: it might be a good idea to move this to cTWUtil int i; for (i = 1; i < argc; ++i) memset((char*)argv[i], 0, strlen(argv[i]) * sizeof(TCHAR)); cCmdLineIter iter(cmdLine); if (iter.SeekToArg(cTWAdminCmdLine::HELP)) { TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_TWADMIN_VERSION) << std::endl; TCOUT << TSS_GetString(cTW, tw::STR_VERSION) << std::endl; //Output a mode specific usage statement TCOUT << pMode->GetModeUsage(); ret = 1; goto exit; } if (iter.SeekToArg(cTWAdminCmdLine::VERBOSE)) { TCERR << TSS_GetString(cTW, tw::STR_VERSION) << std::endl; } // open up the config file, possibly using the passed in path cConfigFile config; bool configFileOpened = false; cErrorBucketNull errorNull; // don't spit errors to the user if (pMode->GetModeID() != cTWAdminCmdLine::MODE_GENERATE_KEYS && pMode->GetModeID() != cTWAdminCmdLine::MODE_CHANGE_PASSPHRASES && pMode->GetModeID() != cTWAdminCmdLine::MODE_CREATE_CONFIG && pMode->GetModeID() != cTWAdminCmdLine::MODE_PRINT_CONFIG && pMode->GetModeID() != cTWAdminCmdLine::MODE_HELP) { try { //open cfg file TSTRING cfgPath; cTWUtil::OpenConfigFile(config, cmdLine, cTWAdminCmdLine::CFG_FILE, errorNull, cfgPath); pMode->SetCfgFilePath(cfgPath); configFileOpened = true; } catch (eError& error) { TSTRING extra; extra += TSS_GetString(cTW, tw::STR_NEWLINE); extra += TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CONFIG_OPEN); cTWUtil::PrintErrorMsg(error, extra); ret = 1; goto exit; } } // ok, now we can initialize the mode object and have it execute if (!pMode->Init(configFileOpened ? &config : NULL, cmdLine)) { TCERR << TSS_GetString(cTW, tw::STR_GET_HELP) << std::endl; ret = 1; goto exit; } ret = pMode->Execute(&twInit.errorQueue); } //end try block catch (eError& error) { cTWUtil::PrintErrorMsg(error); ASSERT(false); ret = 1; } catch (std::bad_alloc& e) { TCERR << _T("*** Fatal exception: Out of memory "); TCERR << _T("*** Exiting...\n"); ret = 1; } catch (std::exception& e) { TCERR << _T("*** Fatal exception: "); std::cerr << e.what() << std::endl; TCERR << _T("*** Exiting...\n"); ret = 1; } /* catch (...) { TCERR << _T("*** Fatal exception occurred.\n"); TCERR << _T("*** Exiting...\n"); ret = 1; } */ exit: return ret; }
/////////////////////////////////////////////////////////////////////////////// // main /////////////////////////////////////////////////////////////////////////////// int __cdecl _tmain( int argc, const TCHAR* argv[ ], const TCHAR* envp[ ] ) { if (TimeBombExploded()) return 8; int ret = 0; cTWInit twInit; try { // set unexpected and terminate handlers // Note: we do this before Init() in case it attempts to call these handlers // TODO: move this into the Init() routine EXCEPTION_NAMESPACE set_terminate(tw_terminate_handler); EXCEPTION_NAMESPACE set_unexpected(tw_unexpected_handler); // Initialization // twInit.Init( argv[0] ); TSS_Dependency( cTripwire ); // set up the debug output cDebug::SetDebugLevel( cDebug::D_DEBUG/*D_DETAIL*//*D_NEVER*/ ); // first, get the right mode... std::auto_ptr<iTWMode> pMode(cTWCmdLine::GetMode(argc, argv)); if(! pMode.get()) { // no valid mode passed; GetMode will display an appropriate string (include usage statement) ret = 8; goto exit; } // if version was requested, output version string and exit if (pMode.get()->GetModeID() == cTWCmdLine::MODE_VERSION) { TCOUT << TSS_GetString( cTW, tw::STR_VERSION_LONG) << std::endl; ret = 0; goto exit; } // process the command line cCmdLineParser cmdLine; pMode->InitCmdLineParser(cmdLine); try { cmdLine.Parse(argc, argv); } catch( eError& e ) { cTWUtil::PrintErrorMsg(e); TCERR << TSS_GetString( cTW, tw::STR_GET_HELP) << std::endl; ret = 8; goto exit; } TSTRING commandLine = util_GetWholeCmdLine( argc, argv ); #if IS_UNIX // erase the command line // TODO: it might be a good idea to move this to cTWUtil int i; for (i = 1; i < argc; ++i) memset((char*)argv[i], 0, strlen(argv[i])*sizeof(TCHAR)); #endif cCmdLineIter iter(cmdLine); if (iter.SeekToArg(cTWCmdLine::HELP)) { TCOUT << TSS_GetString( cTripwire, tripwire::STR_TRIPWIRE_VERSION) << std::endl; TCOUT << TSS_GetString( cTW, tw::STR_VERSION) << std::endl; // //Since --help was passed, exit after emitting a mode-specific usage statement. TCOUT << pMode->GetModeUsage(); ret = 8; goto exit; } if (iter.SeekToArg(cTWCmdLine::VERBOSE)) { TCOUT << TSS_GetString( cTW, tw::STR_VERSION) << std::endl; } // open up the config file, possibly using the passed in path cConfigFile config; TSTRING strConfigFile; cErrorReporter errorReporter; if( pMode->GetModeID() != cTWCmdLine::MODE_HELP ) { try { //open cfg file cTWUtil::OpenConfigFile(config, cmdLine, cTWCmdLine::CFG_FILE, errorReporter, strConfigFile); } catch (eError& error) { TSTRING extra; extra += TSS_GetString( cTW, tw::STR_NEWLINE); extra += TSS_GetString( cTW, tw::STR_ERR_TWCFG_CANT_READ); cTWUtil::PrintErrorMsg( error, extra ); ret = 8; goto exit; } } // ok, now we can initialize the mode object and have it execute pMode->SetCmdLine( commandLine ); pMode->SetConfigFile( strConfigFile ); if(! pMode->Init(config, cmdLine)) { TCERR << TSS_GetString( cTW, tw::STR_GET_HELP) << std::endl; ret = 8; goto exit; } ret = pMode->Execute(&twInit.errorQueue); }//end try block catch (eError& error) { cTWUtil::PrintErrorMsg(error); ASSERT(false); ret = 8; } catch (std::bad_alloc e) { // Note: We use fputs rather than TCERR as it will probably require the // least amount of memory to do its thing. If we ran out of memory we // need to do everything we can to get this string out to the user. fputs("*** Fatal exception: Out of memory\n", stderr); fputs("*** Exiting...\n", stderr); ret = 8; } catch (std::exception e) { TCERR << _T("*** Fatal exception: "); std::cerr << e.what() << std::endl; TCERR << _T("*** Exiting...\n"); ret = 8; } /* catch (...) { TCERR << _T("*** Fatal exception occurred.\n"); TCERR << _T("*** Exiting...\n"); ret = 8; } */ exit: // print out the max memory usage... /* #ifdef _DEBUG TCOUT << _T("Maximum memory footprint = ") << gMaxAlloc << std::endl; #endif */ return ret; } //end MAIN
/** Initialize the driver. Sets signal handlers for SIGINT and SIGSEGV. */ void cvc4_init() { #ifdef CVC4_DEBUG LastExceptionBuffer::setCurrent(new LastExceptionBuffer()); #endif #ifndef __WIN32__ struct rlimit limit; if(getrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("getrlimit() failure: ") + strerror(errno)); } if(limit.rlim_cur != limit.rlim_max) { limit.rlim_cur = limit.rlim_max; if(setrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("setrlimit() failure: ") + strerror(errno)); } if(getrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("getrlimit() failure: ") + strerror(errno)); } } struct sigaction act1; act1.sa_sigaction = sigint_handler; act1.sa_flags = SA_SIGINFO; sigemptyset(&act1.sa_mask); if(sigaction(SIGINT, &act1, NULL)) { throw Exception(string("sigaction(SIGINT) failure: ") + strerror(errno)); } struct sigaction act2; act2.sa_sigaction = timeout_handler; act2.sa_flags = SA_SIGINFO; sigemptyset(&act2.sa_mask); if(sigaction(SIGXCPU, &act2, NULL)) { throw Exception(string("sigaction(SIGXCPU) failure: ") + strerror(errno)); } struct sigaction act3; act3.sa_sigaction = ill_handler; act3.sa_flags = SA_SIGINFO; sigemptyset(&act3.sa_mask); if(sigaction(SIGILL, &act3, NULL)) { throw Exception(string("sigaction(SIGILL) failure: ") + strerror(errno)); } #ifdef HAVE_SIGALTSTACK stack_t ss; ss.ss_sp = (char*) malloc(SIGSTKSZ); if(ss.ss_sp == NULL) { throw Exception("Can't malloc() space for a signal stack"); } ss.ss_size = SIGSTKSZ; ss.ss_flags = 0; if(sigaltstack(&ss, NULL) == -1) { throw Exception(string("sigaltstack() failure: ") + strerror(errno)); } cvc4StackSize = limit.rlim_cur; cvc4StackBase = ss.ss_sp; struct sigaction act4; act4.sa_sigaction = segv_handler; act4.sa_flags = SA_SIGINFO | SA_ONSTACK; sigemptyset(&act4.sa_mask); if(sigaction(SIGSEGV, &act4, NULL)) { throw Exception(string("sigaction(SIGSEGV) failure: ") + strerror(errno)); } #endif /* HAVE_SIGALTSTACK */ struct sigaction act5; act5.sa_sigaction = sigterm_handler; act5.sa_flags = SA_SIGINFO; sigemptyset(&act5.sa_mask); if (sigaction(SIGTERM, &act5, NULL)) { throw Exception(string("sigaction(SIGTERM) failure: ") + strerror(errno)); } #endif /* __WIN32__ */ set_unexpected(cvc4unexpected); default_terminator = set_terminate(cvc4terminate); }
int __cdecl _tmain(int argc, const TCHAR** argv) { int ret = 0; if (CheckEpoch()) return 1; try { // set unexpected and terminate handlers // Note: we do this before Init() in case it attempts to call these handlers // TODO: move this into the Init() routine EXCEPTION_NAMESPACE set_terminate(tw_terminate_handler); EXCEPTION_NAMESPACE set_unexpected(tw_unexpected_handler); //cTWInit twInit( argv[0] ); SiggenInit(); cDebug::SetDebugLevel(cDebug::D_DETAIL); cSiggenCmdLine siggen; // first, process the command line if (argc < 2) { TCOUT << TSS_GetString(cSiggen, siggen::STR_SIGGEN_VERSION) << std::endl; TCOUT << TSS_GetString(cTW, tw::STR_VERSION) << std::endl; TCOUT << TSS_GetString(cTW, tw::STR_GET_HELP) << std::endl; ret = 1; goto exit; } // // Display the version info... // this is quick and dirty ... just the way I like it :-) -- mdb // if (_tcscmp(argv[1], _T("--version")) == 0) { TCOUT << TSS_GetString(cTW, tw::STR_VERSION_LONG) << std::endl; ret = 0; goto exit; } cCmdLineParser cmdLine; siggen.InitCmdLineParser(cmdLine); try { cmdLine.Parse(argc, argv); } catch (eError& e) { cTWUtil::PrintErrorMsg(e); TCERR << TSS_GetString(cTW, tw::STR_GET_HELP) << std::endl; ret = 1; goto exit; } cCmdLineIter iter(cmdLine); if (iter.SeekToArg(cSiggenCmdLine::HELP)) { TCOUT << TSS_GetString(cSiggen, siggen::STR_SIGGEN_VERSION) << std::endl; TCOUT << TSS_GetString(cTW, tw::STR_VERSION) << std::endl; TCOUT << TSS_GetString(cSiggen, siggen::STR_SIGGEN_USAGE) << std::endl; ret = 1; goto exit; } if (!siggen.Init(cmdLine)) { TCOUT << TSS_GetString(cSiggen, siggen::STR_SIGGEN_VERSION) << std::endl; TCOUT << TSS_GetString(cTW, tw::STR_VERSION) << std::endl; TCOUT << TSS_GetString(cSiggen, siggen::STR_SIGGEN_USAGE) << std::endl; ret = 1; goto exit; } ret = siggen.Execute(); } //end try block catch (eError& error) { cErrorReporter::PrintErrorMsg(error); ASSERT(false); } exit: return ret; } //end MAIN
int main() { set_unexpected( &my_unexp ); test_unexp(); return 0; }
// Installs C++ exception handlers that function on per-thread basis int CCrashHandler::SetThreadExceptionHandlers(DWORD dwFlags) { crSetErrorMsg(_T("Unspecified error.")); // If 0 is specified as dwFlags, assume all available exception handlers should be // installed if((dwFlags&0x1FFF)==0) dwFlags |= 0x1FFF; DWORD dwThreadId = GetCurrentThreadId(); CAutoLock lock(&m_csThreadExceptionHandlers); std::map<DWORD, ThreadExceptionHandlers>::iterator it = m_ThreadExceptionHandlers.find(dwThreadId); if(it!=m_ThreadExceptionHandlers.end()) { // handlers are already set for the thread ATLASSERT(0); crSetErrorMsg(_T("Can't install handlers for current thread twice.")); return 1; // failed } ThreadExceptionHandlers handlers; if(dwFlags&CR_INST_TERMINATE_HANDLER) { // Catch terminate() calls. // In a multithreaded environment, terminate functions are maintained // separately for each thread. Each new thread needs to install its own // terminate function. Thus, each thread is in charge of its own termination handling. // http://msdn.microsoft.com/en-us/library/t6fk7h29.aspx handlers.m_prevTerm = set_terminate(TerminateHandler); } if(dwFlags&CR_INST_UNEXPECTED_HANDLER) { // Catch unexpected() calls. // In a multithreaded environment, unexpected functions are maintained // separately for each thread. Each new thread needs to install its own // unexpected function. Thus, each thread is in charge of its own unexpected handling. // http://msdn.microsoft.com/en-us/library/h46t5b69.aspx handlers.m_prevUnexp = set_unexpected(UnexpectedHandler); } if(dwFlags&CR_INST_SIGFPE_HANDLER) { // Catch a floating point error typedef void (*sigh)(int); handlers.m_prevSigFPE = signal(SIGFPE, (sigh)SigfpeHandler); } if(dwFlags&CR_INST_SIGILL_HANDLER) { // Catch an illegal instruction handlers.m_prevSigILL = signal(SIGILL, SigillHandler); } if(dwFlags&CR_INST_SIGSEGV_HANDLER) { // Catch illegal storage access errors handlers.m_prevSigSEGV = signal(SIGSEGV, SigsegvHandler); } // Insert the structure to the list of handlers m_ThreadExceptionHandlers[dwThreadId] = handlers; // OK. crSetErrorMsg(_T("Success.")); return 0; }
InstallUnexpected::InstallUnexpected(void (*func)()) { old = set_unexpected(func); }