Remove catches for non-Trick exceptions

Back-ported changes to not catch unknown exceptions and print a
stack trace to where the exception occurred.

refs #220
This commit is contained in:
Alex Lin 2016-04-15 16:10:53 -05:00
parent 5166946144
commit 56290d0306
10 changed files with 84 additions and 93 deletions

View File

@ -70,6 +70,9 @@ namespace Trick {
/** Allows the trapping of SIGSEGV signals and graceful shutdown.\n */
bool trap_sigsegv; /**< trick_units(--) */
/** Allows the trapping of SIGABRT signals and graceful shutdown.\n */
bool trap_sigabrt; /**< trick_units(--) */
/** Flags a restart was loaded\n */
bool restart_called; /**< trick_io(**) trick_units(--) */
@ -523,6 +526,14 @@ namespace Trick {
*/
bool get_trap_sigsegv() ;
/**
@userdesc Command to get the trap sigsegv toggle value (will SIGSEGV signal be trapped).
@par Python Usage:
@code <my_int> = trick.exec_get_trap_sigsegv() @endcode
@return boolean (C integer 0/1) Executive::trap_sigsegv
*/
bool get_trap_sigabrt() ;
/**
@brief @userdesc Command to set the attach debugger toggle value.
@param on_off - boolean yes (C integer 1) = attach debugger if signal shuts sim down. no (C integer 0) = do not attach debugger.
@ -685,6 +696,18 @@ namespace Trick {
*/
int set_trap_sigsegv(bool on_off) ;
/**
@userdesc Command to enable/disable the trapping of SIGABRT signals and a graceful shutdown.
Setting on_off to true (default) will trap the operating system communications bus error signal and then
perforam a graceful simulation shutdown. If on_off is false, the signal will not be trapped and
termination will occur producing a core file.
@par Python Usage:
@code trick.exec_set_trap_sigabrt(<on_off>) @endcode
@param on_off - boolean yes (C integer 1) = enable trap, no (C integer 0) = disable trap
@return always 0
*/
int set_trap_sigabrt(bool on_off) ;
/**
@userdesc Command to get the simulation time in seconds.
Formula for simulation time is time_tics / time_tic_value.

View File

@ -38,6 +38,7 @@ extern "C" {
int exec_get_trap_sigbus(void) ;
int exec_get_trap_sigfpe(void) ;
int exec_get_trap_sigsegv(void) ;
int exec_get_trap_sigabrt(void) ;
int exec_set_attach_debugger(int on_off) ;
int exec_set_debugger_command(const char * command) ;
@ -68,6 +69,7 @@ extern "C" {
int exec_set_trap_sigbus(int on_off) ;
int exec_set_trap_sigfpe(int on_off) ;
int exec_set_trap_sigsegv(int on_off) ;
int exec_set_trap_sigabrt(int on_off) ;
int exec_set_version_date_tag(const char * tag) ;
int exec_set_build_date(const char * date) ;
int exec_set_current_version(const char * version) ;

View File

@ -57,6 +57,7 @@ Trick::Executive::Executive() {
trap_sigbus = false ;
trap_sigfpe = false ;
trap_sigsegv = false ;
trap_sigabrt = false ;
build_date = std::string("unknown") ;
current_version = std::string("unknown") ;
@ -259,6 +260,10 @@ bool Trick::Executive::get_trap_sigsegv() {
return(trap_sigsegv) ;
}
bool Trick::Executive::get_trap_sigabrt() {
return(trap_sigabrt) ;
}
void Trick::Executive::reset_job_cycle_times() {
unsigned int ii ;
for ( ii = 0 ; ii < all_jobs_vector.size() ; ii++ ) {

View File

@ -378,6 +378,18 @@ extern "C" int exec_get_trap_sigsegv() {
return -1 ;
}
/**
* @relates Trick::Executive
* @copydoc Trick::Executive::get_trap_sigabrt
* C wrapper for Trick::Executive::get_trap_sigabrt
*/
extern "C" int exec_get_trap_sigabrt() {
if ( the_exec != NULL ) {
return (int)the_exec->get_trap_sigabrt() ;
}
return -1 ;
}
// -------------------------- SET ------------------------
/**
@ -593,6 +605,18 @@ extern "C" int exec_set_trap_sigsegv( int on_off ) {
return -1 ;
}
/**
* @relates Trick::Executive
* @copydoc Trick::Executive::set_trap_sigsegv
* C wrapper for Trick::Executive::set_trap_sigsegv
*/
extern "C" int exec_set_trap_sigabrt( int on_off ) {
if ( the_exec != NULL ) {
return the_exec->set_trap_sigabrt((bool)on_off) ;
}
return -1 ;
}
/**
* @relates Trick::Executive
* @copydoc Trick::Executive::set_job_onoff

View File

@ -62,25 +62,6 @@ int Trick::Executive::init() {
except_file = ex.file ;
except_message = ex.message ;
return(-1) ;
} catch (const std::exception &ex) {
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::init" ;
}
fprintf(stderr, "\nExecutive::loop terminated with std::exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n",
except_file.c_str(), ex.what()) ;
exit(-1) ;
} catch (...) {
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::init" ;
}
except_message = "unknown error" ;
fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n",
except_file.c_str() , except_message.c_str()) ;
exit(-1) ;
}
/* return 0 if there are no errors. */

View File

@ -112,7 +112,32 @@ int Trick::Executive::set_trap_sigsegv(bool on_off) {
/**
@details
-# Catch SIGBUS and SIGSEGV errors. Don't catch SIGFPE
-# If incoming on_off flag is true assign sig_hand() as the signal handler for SIGSEGV
-# Else revert to the default signal handler SIG_DFL.
-# set trap_sigabrt to the current on_off status
Requirement [@ref r_exec_signal_0].
*/
int Trick::Executive::set_trap_sigabrt(bool on_off) {
static struct sigaction sigact;
if ( on_off ) {
/* Assign sig_hand() as the signal handler for SIGABRT */
sigact.sa_handler = (void (*)(int)) sig_hand;
} else {
sigact.sa_handler = SIG_DFL;
}
if (sigaction(SIGABRT, &sigact, NULL) < 0) {
perror("sigaction() failed for SIGSEGV");
} else {
trap_sigabrt = on_off ;
}
return(0) ;
}
/**
@details
-# Catch SIGBUS, SIGSEGV, and SIGABRT errors. Don't catch SIGFPE
-# Assign ctrl_c_hand() as the signal handler for SIGINT.
Requirement [@ref r_exec_signal_0].
-# Assign sig_hand() as the signal handler for SIGTERM.
@ -128,6 +153,7 @@ int Trick::Executive::init_signal_handlers() {
set_trap_sigbus(true) ;
set_trap_sigfpe(false) ;
set_trap_sigsegv(true) ;
set_trap_sigabrt(true) ;
/* Assign ctrl_c_hand() as the default signal handler for SIGINT (<CTRL-C> keypress). */
sigact.sa_handler = (void (*)(int)) ctrl_c_hand;

View File

@ -52,26 +52,6 @@ int Trick::Executive::loop() {
except_file = ex.file ;
except_message = ex.message ;
return(ex.ret_code) ;
} catch (const std::exception &ex) {
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::run" ;
}
fprintf(stderr, "\nExecutive::loop terminated with std::exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n"
" STOP TIME: %f\n" , except_file.c_str() , ex.what() , get_sim_time()) ;
exit(-1) ;
} catch (...) {
/* Handle unknown exceptions. Set the file name and error message to unknown. exit -1. */
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::run" ;
}
except_message = "unknown error" ;
fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n"
" STOP TIME: %f\n" , except_file.c_str() , except_message.c_str() , get_sim_time()) ;
exit(-1) ;
}
/* return 0 if there are no errors. */

View File

@ -73,19 +73,6 @@ int Trick::Executive::shutdown() {
except_return = ex.ret_code ;
except_file += std::string(" then exception caught in ") + ex.file ;
except_message += std::string(" then exception Message: ") + ex.message ;
} catch (const std::exception &ex) {
except_return = -1 ;
if ( curr_job != NULL ) {
except_file += " " + curr_job->name ;
} else {
except_file += " somewhere in Executive::shutdown" ;
}
except_message += std::string("standard exception caught") + ex.what();
} catch (...) {
/* Handle unknown exceptions. Set the file name and error message to unknown. Return -1. */
except_return = -1 ;
except_file = "somewhere in shutdown()" ;
except_message = "unknown error" ;
}
getrusage(RUSAGE_SELF, &cpu_usage_buf);

View File

@ -45,6 +45,9 @@ void Trick::Executive::signal_handler(int sig) {
case SIGSEGV: /* Segmentation fault */
write( 2 , "SIGSEGV" , 7 ) ;
break;
case SIGABRT: /* Abort */
write( 2 , "SIGABRT" , 7 ) ;
break;
default: /* Unrecognized signal */
write( 2 , "unknown" , 7 ) ;
break;

View File

@ -218,51 +218,11 @@ void * Trick::Threads::thread_body() {
" THREAD STOP TIME: %f\n" ,
thread_id, ex.file.c_str(), ex.message.c_str(), exec_get_sim_time()) ;
exit(ex.ret_code) ;
} catch (const std::exception &ex) {
std::string except_file ;
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::run" ;
}
fprintf(stderr, "\nCHILD THREAD %d TERMINATED with exec_terminate\n ROUTINE: %s\n DIAGNOSTIC: %s\n"
" THREAD STOP TIME: %f\n" ,
thread_id, except_file.c_str() , ex.what(), exec_get_sim_time()) ;
exit(-1) ;
#ifdef __linux
#ifdef __GNUC__
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
// for post gcc 4.1.2
} catch (abi::__forced_unwind&) {
//pthread_exit and pthread_cancel will cause an abi::__forced_unwind to be thrown. Rethrow it.
throw;
#endif
#endif
#endif
} catch (...) {
/*
In gcc 4.1.2 I cannot find the catch type for the pthread_cancel forced_unwind exception so I changed
the catch here to just rethrow all unknown exceptions. For the other architectures
we signal the main thread for an orderly shutdown.
*/
#ifdef __linux
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ == 1
throw;
#else
std::string except_file ;
std::string except_message ;
if ( curr_job != NULL ) {
except_file = curr_job->name ;
} else {
except_file = "somewhere in Executive::run" ;
}
except_message = "unknown error" ;
fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n"
" STOP TIME: %f\n" , except_file.c_str() , except_message.c_str() , exec_get_sim_time()) ;
exit(-1) ;
#endif
#endif
#endif
}