Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/preemption.c

    r2e9aed4 r258e6ad5  
    1919extern "C" {
    2020#include <errno.h>
     21#include <execinfo.h>
     22#define __USE_GNU
     23#include <signal.h>
     24#undef __USE_GNU
    2125#include <stdio.h>
    2226#include <string.h>
     
    2529#undef ftype
    2630
    27 #include "bits/signal.h"
     31#ifdef __USE_STREAM__
     32#include "fstream"
     33#endif
    2834
    2935//TODO move to defaults
     
    3440        return __CFA_DEFAULT_PREEMPTION__;
    3541}
     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
    3646
    3747// FwdDeclarations : timeout handlers
     
    4353void sigHandler_segv     ( __CFA_SIGPARMS__ );
    4454void sigHandler_abort    ( __CFA_SIGPARMS__ );
     55
     56// FwdDeclarations : sigaction wrapper
     57static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    4558
    4659// FwdDeclarations : alarm thread main
     
    169182        void enable_interrupts_noPoll() {
    170183                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    171                 verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
     184                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interrupts
    172185        }
    173186}
     
    233246        // Setup proper signal handlers
    234247        __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
    235250
    236251        signal_block( SIGALRM );
     
    293308        if( !preemption_ready() ) { return; }
    294309
    295         __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
     310        // __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    296311
    297312        preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     
    365380}
    366381
     382// Sigaction wrapper : register an signal handler
     383static 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
     399static 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
    367511// Local Variables: //
    368512// mode: c //
Note: See TracChangeset for help on using the changeset viewer.