Changeset dbe9b08


Ignore:
Timestamp:
Jan 25, 2018, 5:02:09 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
91496f3
Parents:
6e0f4bd
Message:

Spinlocks are now non-preemptive, stack-traces should print correctly

Location:
src/libcfa
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/bits/locks.h

    r6e0f4bd rdbe9b08  
    5858
    5959#ifdef __cforall
     60        extern "C" {
     61                extern void disable_interrupts();
     62                extern void enable_interrupts_noPoll();
     63        }
     64
    6065        extern void yield( unsigned int );
    6166        extern thread_local struct thread_desc *    volatile this_thread;
     
    6873        static inline _Bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
    6974                _Bool result = __lock_test_and_test_and_set( this.lock );
    70                 __cfaabi_dbg_debug_do(
    71                         if( result ) {
     75                if( result ) {
     76                        disable_interrupts();
     77                        __cfaabi_dbg_debug_do(
    7278                                this.prev_name = caller;
    7379                                this.prev_thrd = this_thread;
    74                         }
    75                 )
     80                        )
     81                }
    7682                return result;
    7783        }
     
    99105                        #endif
    100106                }
     107                disable_interrupts();
    101108                __cfaabi_dbg_debug_do(
    102109                        this.prev_name = caller;
     
    111118                        yield( i );
    112119                }
     120                disable_interrupts();
    113121                __cfaabi_dbg_debug_do(
    114122                        this.prev_name = caller;
     
    119127        static inline void unlock( __spinlock_t & this ) {
    120128                __lock_release( this.lock );
     129                enable_interrupts_noPoll();
    121130        }
    122131#endif
  • src/libcfa/concurrency/kernel.c

    r6e0f4bd rdbe9b08  
    516516}
    517517
     518//=============================================================================================
     519// Unexpected Terminating logic
     520//=============================================================================================
     521
     522
    518523static __spinlock_t kernel_abort_lock;
    519524static __spinlock_t kernel_debug_lock;
  • src/libcfa/concurrency/preemption.c

    r6e0f4bd rdbe9b08  
    1919extern "C" {
    2020#include <errno.h>
    21 #include <execinfo.h>
    22 #define __USE_GNU
    23 #include <signal.h>
    24 #undef __USE_GNU
    2521#include <stdio.h>
    2622#include <string.h>
     
    2925#undef ftype
    3026
    31 #ifdef __USE_STREAM__
    32 #include "fstream"
    33 #endif
     27#include "bits/signal.h"
    3428
    3529//TODO move to defaults
     
    4034        return __CFA_DEFAULT_PREEMPTION__;
    4135}
    42 
    43 // Short hands for signal context information
    44 #define __CFA_SIGCXT__ ucontext_t *
    45 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt
    4636
    4737// FwdDeclarations : timeout handlers
     
    5343void sigHandler_segv     ( __CFA_SIGPARMS__ );
    5444void sigHandler_abort    ( __CFA_SIGPARMS__ );
    55 
    56 // FwdDeclarations : sigaction wrapper
    57 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    5845
    5946// FwdDeclarations : alarm thread main
     
    246233        // Setup proper signal handlers
    247234        __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART );         // CtxSwitch handler
    248         // __kernel_sigaction( SIGSEGV, sigHandler_segv     , SA_SIGINFO );      // Failure handler
    249         // __kernel_sigaction( SIGBUS , sigHandler_segv     , SA_SIGINFO );      // Failure handler
    250235
    251236        signal_block( SIGALRM );
     
    380365}
    381366
    382 // Sigaction wrapper : register an signal handler
    383 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
    384         struct sigaction act;
    385 
    386         act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
    387         act.sa_flags = flags;
    388 
    389         if ( sigaction( sig, &act, NULL ) == -1 ) {
    390                 __cfaabi_dbg_print_buffer_decl(
    391                         " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
    392                         sig, handler, flags, errno, strerror( errno )
    393                 );
    394                 _exit( EXIT_FAILURE );
    395         }
    396 }
    397 
    398 // Sigaction wrapper : restore default handler
    399 static void __kernel_sigdefault( int sig ) {
    400         struct sigaction act;
    401 
    402         act.sa_handler = SIG_DFL;
    403         act.sa_flags = 0;
    404         sigemptyset( &act.sa_mask );
    405 
    406         if ( sigaction( sig, &act, NULL ) == -1 ) {
    407                 __cfaabi_dbg_print_buffer_decl(
    408                         " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    409                         sig, errno, strerror( errno )
    410                 );
    411                 _exit( EXIT_FAILURE );
    412         }
    413 }
    414 
    415 //=============================================================================================
    416 // Terminating Signals logic
    417 //=============================================================================================
    418 
    419 __cfaabi_dbg_debug_do(
    420         static void __kernel_backtrace( int start ) {
    421                 // skip first N stack frames
    422 
    423                 enum { Frames = 50 };
    424                 void * array[Frames];
    425                 int size = backtrace( array, Frames );
    426                 char ** messages = backtrace_symbols( array, size );
    427 
    428                 // find executable name
    429                 *index( messages[0], '(' ) = '\0';
    430                 #ifdef __USE_STREAM__
    431                 serr | "Stack back trace for:" | messages[0] | endl;
    432                 #else
    433                 fprintf( stderr, "Stack back trace for: %s\n", messages[0]);
    434                 #endif
    435 
    436                 // skip last 2 stack frames after main
    437                 for ( int i = start; i < size && messages != NULL; i += 1 ) {
    438                         char * name = NULL;
    439                         char * offset_begin = NULL;
    440                         char * offset_end = NULL;
    441 
    442                         for ( char *p = messages[i]; *p; ++p ) {
    443                                 // find parantheses and +offset
    444                                 if ( *p == '(' ) {
    445                                         name = p;
    446                                 }
    447                                 else if ( *p == '+' ) {
    448                                         offset_begin = p;
    449                                 }
    450                                 else if ( *p == ')' ) {
    451                                         offset_end = p;
    452                                         break;
    453                                 }
    454                         }
    455 
    456                         // if line contains symbol print it
    457                         int frameNo = i - start;
    458                         if ( name && offset_begin && offset_end && name < offset_begin ) {
    459                                 // delimit strings
    460                                 *name++ = '\0';
    461                                 *offset_begin++ = '\0';
    462                                 *offset_end++ = '\0';
    463 
    464                                 #ifdef __USE_STREAM__
    465                                 serr    | "("  | frameNo | ")" | messages[i] | ":"
    466                                         | name | "+" | offset_begin | offset_end | endl;
    467                                 #else
    468                                 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
    469                                 #endif
    470                         }
    471                         // otherwise, print the whole line
    472                         else {
    473                                 #ifdef __USE_STREAM__
    474                                 serr | "(" | frameNo | ")" | messages[i] | endl;
    475                                 #else
    476                                 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );
    477                                 #endif
    478                         }
    479                 }
    480 
    481                 free( messages );
    482         }
    483 )
    484 
    485 // void sigHandler_segv( __CFA_SIGPARMS__ ) {
    486 //      __cfaabi_dbg_debug_do(
    487 //              #ifdef __USE_STREAM__
    488 //              serr    | "*CFA runtime error* program cfa-cpp terminated with"
    489 //                      | (sig == SIGSEGV ? "segment fault." : "bus error.")
    490 //                      | endl;
    491 //              #else
    492 //              fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );
    493 //              #endif
    494 
    495 //              // skip first 2 stack frames
    496 //              __kernel_backtrace( 1 );
    497 //      )
    498 //      exit( EXIT_FAILURE );
    499 // }
    500 
    501 // void sigHandler_abort( __CFA_SIGPARMS__ ) {
    502 //      // skip first 6 stack frames
    503 //      __cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); )
    504 
    505 //      // reset default signal handler
    506 //      __kernel_sigdefault( SIGABRT );
    507 
    508 //      raise( SIGABRT );
    509 // }
    510 
    511367// Local Variables: //
    512368// mode: c //
  • src/libcfa/interpose.c

    r6e0f4bd rdbe9b08  
    2222#include <dlfcn.h>
    2323#include <unistd.h>
     24#define __USE_GNU
     25#include <signal.h>
     26#undef __USE_GNU
     27#include <execinfo.h>
    2428}
    2529
    2630#include "bits/debug.h"
    2731#include "bits/defs.h"
     32#include "bits/signal.h"
    2833#include "startup.h"
    2934
     
    8489#define INIT_REALRTN( x, ver ) assign_ptr( (void**)&libc_##x, #x, ver)
    8590
     91void sigHandler_segv ( __CFA_SIGPARMS__ );
     92void sigHandler_abort( __CFA_SIGPARMS__ );
     93
    8694void interpose_startup() {
    8795        const char *version = NULL;
     
    8997        INIT_REALRTN( abort, version );
    9098        INIT_REALRTN( exit, version );
    91 }
     99
     100        __kernel_sigaction( SIGSEGV, sigHandler_segv     , SA_SIGINFO );      // Failure handler
     101        __kernel_sigaction( SIGBUS , sigHandler_segv     , SA_SIGINFO );      // Failure handler
     102}
     103
     104//=============================================================================================
     105// Terminating Signals logic
     106//=============================================================================================
    92107
    93108extern "C" {
     
    137152                libc_abort();
    138153        }
     154}
     155
     156// skip first 6 stack frames by default
     157static void __kernel_backtrace() {
     158        // skip first N stack frames
     159        int start = 6;
     160
     161        enum { Frames = 50 };
     162        void * array[Frames];
     163        int size = backtrace( array, Frames );
     164        char ** messages = backtrace_symbols( array, size );
     165
     166        // find executable name
     167        *index( messages[0], '(' ) = '\0';
     168        __cfaabi_dbg_bits_print_nolock( "Stack back trace for: %s\n", messages[0]);
     169
     170        // skip last 2 stack frames after main
     171        for ( int i = start; i < size && messages != NULL; i += 1 ) {
     172                char * name = NULL;
     173                char * offset_begin = NULL;
     174                char * offset_end = NULL;
     175
     176                for ( char *p = messages[i]; *p; ++p ) {
     177                        // find parantheses and +offset
     178                        if ( *p == '(' ) {
     179                                name = p;
     180                        }
     181                        else if ( *p == '+' ) {
     182                                offset_begin = p;
     183                        }
     184                        else if ( *p == ')' ) {
     185                                offset_end = p;
     186                                break;
     187                        }
     188                }
     189
     190                // if line contains symbol print it
     191                int frameNo = i - start;
     192                if ( name && offset_begin && offset_end && name < offset_begin ) {
     193                        // delimit strings
     194                        *name++ = '\0';
     195                        *offset_begin++ = '\0';
     196                        *offset_end++ = '\0';
     197
     198                        __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
     199                }
     200                // otherwise, print the whole line
     201                else {
     202                        __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] );
     203                }
     204        }
     205
     206        free( messages );
     207}
     208
     209void sigHandler_segv( __CFA_SIGPARMS__ ) {
     210        // skip first only 1 stack frames in case of segfault.
     211        abortf( "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );
     212}
     213
     214void sigHandler_abort( __CFA_SIGPARMS__ ) {
     215        __kernel_backtrace();
     216
     217        // reset default signal handler
     218        __kernel_sigdefault( SIGABRT );
     219
     220        raise( SIGABRT );
    139221}
    140222
Note: See TracChangeset for help on using the changeset viewer.