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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.