Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/interpose.cfa

    r92bfda0 r6011658  
    125125
    126126                // Failure handler
    127                  // internal errors
    128                 __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Invalid memory reference (default: Core)
    129                 __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Bus error, bad memory access (default: Core)
    130                 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK ); // Illegal Instruction (default: Core)
    131                 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK ); // Floating-point exception (default: Core)
    132 
    133                 // handlers to outside errors
    134                 // reset in-case they insist and send it over and over
    135                 __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Termination signal (default: Term)
    136                 __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Interrupt from keyboard (default: Term)
    137                 __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Hangup detected on controlling terminal or death of controlling process (default: Term)
    138                 __cfaabi_sigaction( SIGQUIT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Quit from keyboard (default: Core)
    139                 __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Abort signal from abort(3) (default: Core)
     127                __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     128                __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     129                __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK );
     130                __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK );
     131                __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default
     132                __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     133                __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     134                __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup
    140135        }
    141136}
     
    168163}
    169164
    170 // See concurrency/kernel.cfa and concurrency/preemption.cfa for strong definition used in multi-processor mode.
    171 void __kernel_abort_lock( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
    172 void __kernel_abort_msg( char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
    173 int __kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
     165void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
     166void kernel_abort_msg( void * data, char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     167// See concurrency/kernel.cfa for strong definition used in multi-processor mode.
     168int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    174169
    175170enum { abort_text_size = 1024 };
     
    178173static void __cfaabi_backtrace( int start ) {
    179174        enum { Frames = 50, };                                                          // maximum number of stack frames
    180         int last = __kernel_abort_lastframe();                          // skip last N stack frames
     175        int last = kernel_abort_lastframe();                            // skip last N stack frames
    181176
    182177        void * array[Frames];
     
    225220}
    226221
    227 static volatile bool __abort_first = 0;
     222static volatile int __abort_stage = 0;
    228223
    229224// Cannot forward va_list.
    230225void __abort( bool signalAbort, const char fmt[], va_list args ) {
    231         // Multiple threads can come here from multiple paths
    232         // To make sure this is safe any concurrent/subsequent call to abort is redirected to libc-abort
    233         bool first = ! __atomic_test_and_set( &__abort_first, __ATOMIC_SEQ_CST);
    234 
    235         // Prevent preemption from kicking-in and messing with the abort
    236         __kernel_abort_lock();
    237 
    238         // first to abort ?
    239         if ( !first ) {
    240                 // We aren't the first to abort just let C handle it
    241                 signal( SIGABRT, SIG_DFL );     // restore default in case we came here through the function.
     226        int stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     227
     228        // First stage: stop the cforall kernel and print
     229        if(stage == 1) {
     230                // increment stage
     231                stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     232
     233                // must be done here to lock down kernel
     234                void * kernel_data = kernel_abort();
     235                int len;
     236
     237                signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
     238
     239                len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
     240                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     241
     242                assert( fmt );
     243                len = vsnprintf( abort_text, abort_text_size, fmt, args );
     244                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     245
     246                // add optional newline if missing at the end of the format text
     247                if ( fmt[strlen( fmt ) - 1] != '\n' ) {
     248                        __cfaabi_bits_write( STDERR_FILENO, "\n", 1 );
     249                } // if
     250                kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     251        }
     252
     253        // Second stage: print the backtrace
     254        if(stage == 2) {
     255                // increment stage
     256                stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     257
     258                // print stack trace in handler
     259                __cfaabi_backtrace( signalAbort ? 4 : 2 );
     260        }
     261
     262        do {
     263                // Finally call abort
    242264                __cabi_libc.abort();
    243         }
    244 
    245         int len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
    246         __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    247 
    248         // print the cause of the error
    249         assert( fmt );
    250         len = vsnprintf( abort_text, abort_text_size, fmt, args );
    251         __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    252 
    253         // add optional newline if missing at the end of the format text
    254         if ( fmt[strlen( fmt ) - 1] != '\n' ) {
    255                 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 );
    256         } // if
    257 
    258         // Give the kernel the chance to add some data in here
    259         __kernel_abort_msg( abort_text, abort_text_size );
    260 
    261         // print stack trace in handler
    262         __cfaabi_backtrace( signalAbort ? 4 : 2 );
    263 
    264         // Finally call abort
    265         __cabi_libc.abort();
    266 
     265
     266                // Loop so that we never return
     267        } while(true);
    267268}
    268269
Note: See TracChangeset for help on using the changeset viewer.