Changeset 92bfda0


Ignore:
Timestamp:
Jan 20, 2021, 4:40:28 PM (8 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
dafbde8
Parents:
78a8440
Message:

Revisited abort again to be more streamlined and simple.

Location:
libcfa/src
Files:
3 edited

Legend:

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

    r78a8440 r92bfda0  
    624624// Unexpected Terminating logic
    625625//=============================================================================================
    626 
    627 extern "C" {
    628         extern void __cfaabi_real_abort(void);
    629 }
    630 static volatile bool kernel_abort_called = false;
    631 
    632 void * 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 
    650 void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) {
    651         $thread * thrd = ( $thread * ) kernel_data;
     626void __kernel_abort_msg( char * abort_text, int abort_text_size ) {
     627        $thread * thrd = __cfaabi_tls.this_thread;
    652628
    653629        if(thrd) {
     
    669645}
    670646
    671 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    672         return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2;
     647int __kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
     648        return get_coroutine(__cfaabi_tls.this_thread) == get_coroutine(mainThread) ? 4 : 2;
    673649}
    674650
  • libcfa/src/concurrency/preemption.cfa

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

    r78a8440 r92bfda0  
    125125
    126126                // Failure handler
    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
     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)
    135140        }
    136141}
     
    163168}
    164169
    165 void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
    166 void 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.
    168 int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
     170// See concurrency/kernel.cfa and concurrency/preemption.cfa for strong definition used in multi-processor mode.
     171void __kernel_abort_lock( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     172void __kernel_abort_msg( char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     173int __kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    169174
    170175enum { abort_text_size = 1024 };
     
    173178static void __cfaabi_backtrace( int start ) {
    174179        enum { Frames = 50, };                                                          // maximum number of stack frames
    175         int last = kernel_abort_lastframe();                            // skip last N stack frames
     180        int last = __kernel_abort_lastframe();                          // skip last N stack frames
    176181
    177182        void * array[Frames];
     
    220225}
    221226
    222 static volatile int __abort_stage = 0;
     227static volatile bool __abort_first = 0;
    223228
    224229// Cannot forward va_list.
    225230void __abort( bool signalAbort, const char fmt[], va_list args ) {
    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
     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.
    264242                __cabi_libc.abort();
    265 
    266                 // Loop so that we never return
    267         } while(true);
     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
    268267}
    269268
     
    282281    // CONTROL NEVER REACHES HERE!
    283282    va_end( args );
    284 }
    285 
    286 extern "C" {
    287         void __cfaabi_real_abort(void) {
    288                 __cabi_libc.abort();
    289         }
    290283}
    291284
Note: See TracChangeset for help on using the changeset viewer.