Changes in / [dafbde8:fd54fef]


Ignore:
Location:
libcfa/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel.cfa

    rdafbde8 rfd54fef  
    624624// Unexpected Terminating logic
    625625//=============================================================================================
    626 void __kernel_abort_msg( char * abort_text, int abort_text_size ) {
    627         $thread * thrd = __cfaabi_tls.this_thread;
     626
     627extern "C" {
     628        extern void __cfaabi_real_abort(void);
     629}
     630static volatile bool kernel_abort_called = false;
     631
     632void * kernel_abort(void) __attribute__ ((__nothrow__)) {
     633        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
     634        // the globalAbort flag is true.
     635        bool first = !__atomic_test_and_set( &kernel_abort_called, __ATOMIC_SEQ_CST);
     636
     637        // first task to abort ?
     638        if ( !first ) {
     639                // We aren't the first to abort.
     640                // I give up, just let C handle it
     641                __cfaabi_real_abort();
     642        }
     643
     644        // disable interrupts, it no longer makes sense to try to interrupt this processor
     645        disable_interrupts();
     646
     647        return __cfaabi_tls.this_thread;
     648}
     649
     650void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) {
     651        $thread * thrd = ( $thread * ) kernel_data;
    628652
    629653        if(thrd) {
     
    645669}
    646670
    647 int __kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    648         return get_coroutine(__cfaabi_tls.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     671int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
     672        return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2;
    649673}
    650674
  • libcfa/src/concurrency/preemption.cfa

    rdafbde8 rfd54fef  
    616616}
    617617
    618 // Prevent preemption since we are about to start terminating things
    619 void __kernel_abort_lock(void) {
    620         signal_block( SIGUSR1 );
    621 }
    622 
    623618// Raii ctor/dtor for the preemption_scope
    624619// Used by thread to control when they want to receive preemption signals
  • libcfa/src/interpose.cfa

    rdafbde8 rfd54fef  
    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
     
    281282    // CONTROL NEVER REACHES HERE!
    282283    va_end( args );
     284}
     285
     286extern "C" {
     287        void __cfaabi_real_abort(void) {
     288                __cabi_libc.abort();
     289        }
    283290}
    284291
Note: See TracChangeset for help on using the changeset viewer.