- Timestamp:
- Sep 18, 2024, 4:51:28 PM (3 months ago)
- Branches:
- master
- Children:
- 0185b68
- Parents:
- 59627b3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main.cpp
r59627b3 rf660b10 125 125 static void dump( ast::TranslationUnit && transUnit, ostream & out = cout ); 126 126 127 static void backtrace( int start ) { // skip first N stack frames 128 enum { Frames = 50, }; // maximum number of stack frames 129 void * array[Frames]; 130 size_t size = ::backtrace( array, Frames ); 131 char ** messages = ::backtrace_symbols( array, size ); // does not demangle names 132 133 *index( messages[0], '(' ) = '\0'; // find executable name 134 cerr << "Stack back trace for: " << messages[0] << endl; 135 136 // skip last 2 stack frames after main 137 for ( unsigned int i = start; i < size - 2 && messages != nullptr; i += 1 ) { 138 char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr; 139 140 for ( char * p = messages[i]; *p; p += 1 ) { // find parantheses and +offset 141 if ( *p == '(' ) { 142 mangled_name = p; 143 } else if ( *p == '+' ) { 144 offset_begin = p; 145 } else if ( *p == ')' ) { 146 offset_end = p; 147 break; 148 } // if 149 } // for 150 151 // if line contains symbol, attempt to demangle 152 int frameNo = i - start; 153 if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin ) { 154 *mangled_name++ = '\0'; // delimit strings 155 *offset_begin++ = '\0'; 156 *offset_end++ = '\0'; 157 158 int status; 159 char * real_name = __cxxabiv1::__cxa_demangle( mangled_name, 0, 0, &status ); 160 // bug in __cxa_demangle for single-character lower-case non-mangled names 161 if ( status == 0 ) { // demangling successful ? 162 cerr << "(" << frameNo << ") " << messages[i] << " : " 163 << real_name << "+" << offset_begin << offset_end << endl; 164 } else { // otherwise, output mangled name 165 cerr << "(" << frameNo << ") " << messages[i] << " : " 166 << mangled_name << "(/*unknown*/)+" << offset_begin << offset_end << endl; 167 } // if 168 169 free( real_name ); 170 } else { // otherwise, print the whole line 171 cerr << "(" << frameNo << ") " << messages[i] << endl; 172 } // if 173 } // for 174 175 free( messages ); 176 } // backtrace 177 178 #define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused )) 179 180 static void _Signal(struct sigaction & act, int sig, int flags ) { 181 sigemptyset( &act.sa_mask ); 182 act.sa_flags = flags; 183 184 if ( sigaction( sig, &act, nullptr ) == -1 ) { 185 cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl; 186 _exit( EXIT_FAILURE ); 187 } // if 188 } 189 190 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) { 191 struct sigaction act; 192 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; 193 _Signal(act, sig, flags); 194 } // Signal 195 196 static void Signal( int sig, void (* handler)(int), int flags ) { 197 struct sigaction act; 198 act.sa_handler = handler; 199 _Signal(act, sig, flags); 200 } // Signal 201 202 static void sigSegvBusHandler( SIGPARMS ) { 203 if ( sfp->si_addr == nullptr ) { 204 cerr << "Null pointer (nullptr) dereference." << endl; 205 } else { 206 cerr << (sig == SIGSEGV ? "Segment fault" : "Bus error") << " at memory location " << sfp->si_addr << "." << endl 207 << "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript." << endl; 208 } // if 209 backtrace( 2 ); // skip first 2 stack frames 210 abort(); // cause core dump for debugging 211 } // sigSegvBusHandler 212 213 static void sigFpeHandler( SIGPARMS ) { 214 const char * msg; 215 216 switch ( sfp->si_code ) { 217 case FPE_INTDIV: case FPE_FLTDIV: msg = "divide by zero"; break; 218 case FPE_FLTOVF: msg = "overflow"; break; 219 case FPE_FLTUND: msg = "underflow"; break; 220 case FPE_FLTRES: msg = "inexact result"; break; 221 case FPE_FLTINV: msg = "invalid operation"; break; 222 default: msg = "unknown"; 223 } // choose 224 cerr << "Computation error " << msg << " at location " << sfp->si_addr << endl 225 << "Possible cause is constant-expression evaluation invalid." << endl; 226 backtrace( 2 ); // skip first 2 stack frames 227 abort(); // cause core dump for debugging 228 } // sigFpeHandler 229 230 static void sigAbortHandler( SIGPARMS ) { 231 backtrace( 6 ); // skip first 6 stack frames 232 Signal( SIGABRT, SIG_DFL, SA_SIGINFO ); // reset default signal handler 233 raise( SIGABRT ); // reraise SIGABRT 234 } // sigAbortHandler 127 static void backtrace( int start ); 128 static void initSignals(); 235 129 236 130 int main( int argc, char * argv[] ) { … … 239 133 ast::TranslationUnit transUnit; 240 134 241 Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO ); 242 Signal( SIGBUS, sigSegvBusHandler, SA_SIGINFO ); 243 Signal( SIGFPE, sigFpeHandler, SA_SIGINFO ); 244 Signal( SIGABRT, sigAbortHandler, SA_SIGINFO ); 135 initSignals(); 245 136 246 137 // cout << "main" << endl; … … 713 604 } 714 605 606 static void backtrace( int start ) { // skip first N stack frames 607 enum { Frames = 50, }; // maximum number of stack frames 608 void * array[Frames]; 609 size_t size = ::backtrace( array, Frames ); 610 char ** messages = ::backtrace_symbols( array, size ); // does not demangle names 611 612 *index( messages[0], '(' ) = '\0'; // find executable name 613 cerr << "Stack back trace for: " << messages[0] << endl; 614 615 // skip last 2 stack frames after main 616 for ( unsigned int i = start; i < size - 2 && messages != nullptr; i += 1 ) { 617 char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr; 618 619 for ( char * p = messages[i]; *p; p += 1 ) { // find parantheses and +offset 620 if ( *p == '(' ) { 621 mangled_name = p; 622 } else if ( *p == '+' ) { 623 offset_begin = p; 624 } else if ( *p == ')' ) { 625 offset_end = p; 626 break; 627 } // if 628 } // for 629 630 // if line contains symbol, attempt to demangle 631 int frameNo = i - start; 632 if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin ) { 633 *mangled_name++ = '\0'; // delimit strings 634 *offset_begin++ = '\0'; 635 *offset_end++ = '\0'; 636 637 int status; 638 char * real_name = __cxxabiv1::__cxa_demangle( mangled_name, 0, 0, &status ); 639 // bug in __cxa_demangle for single-character lower-case non-mangled names 640 if ( status == 0 ) { // demangling successful ? 641 cerr << "(" << frameNo << ") " << messages[i] << " : " 642 << real_name << "+" << offset_begin << offset_end << endl; 643 } else { // otherwise, output mangled name 644 cerr << "(" << frameNo << ") " << messages[i] << " : " 645 << mangled_name << "(/*unknown*/)+" << offset_begin << offset_end << endl; 646 } // if 647 648 free( real_name ); 649 } else { // otherwise, print the whole line 650 cerr << "(" << frameNo << ") " << messages[i] << endl; 651 } // if 652 } // for 653 654 free( messages ); 655 } // backtrace 656 657 #define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused )) 658 659 static void _Signal(struct sigaction & act, int sig, int flags ) { 660 sigemptyset( &act.sa_mask ); 661 act.sa_flags = flags; 662 663 if ( sigaction( sig, &act, nullptr ) == -1 ) { 664 cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl; 665 _exit( EXIT_FAILURE ); 666 } // if 667 } 668 669 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) { 670 struct sigaction act; 671 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; 672 _Signal(act, sig, flags); 673 } // Signal 674 675 static void Signal( int sig, void (* handler)(int), int flags ) { 676 struct sigaction act; 677 act.sa_handler = handler; 678 _Signal(act, sig, flags); 679 } // Signal 680 681 static void sigSegvBusHandler( SIGPARMS ) { 682 if ( sfp->si_addr == nullptr ) { 683 cerr << "Null pointer (nullptr) dereference." << endl; 684 } else { 685 cerr << (sig == SIGSEGV ? "Segment fault" : "Bus error") << " at memory location " << sfp->si_addr << "." << endl 686 << "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript." << endl; 687 } // if 688 backtrace( 2 ); // skip first 2 stack frames 689 abort(); // cause core dump for debugging 690 } // sigSegvBusHandler 691 692 static void sigFpeHandler( SIGPARMS ) { 693 const char * msg; 694 695 switch ( sfp->si_code ) { 696 case FPE_INTDIV: case FPE_FLTDIV: msg = "divide by zero"; break; 697 case FPE_FLTOVF: msg = "overflow"; break; 698 case FPE_FLTUND: msg = "underflow"; break; 699 case FPE_FLTRES: msg = "inexact result"; break; 700 case FPE_FLTINV: msg = "invalid operation"; break; 701 default: msg = "unknown"; 702 } // choose 703 cerr << "Computation error " << msg << " at location " << sfp->si_addr << endl 704 << "Possible cause is constant-expression evaluation invalid." << endl; 705 backtrace( 2 ); // skip first 2 stack frames 706 abort(); // cause core dump for debugging 707 } // sigFpeHandler 708 709 static void sigAbortHandler( SIGPARMS ) { 710 backtrace( 6 ); // skip first 6 stack frames 711 Signal( SIGABRT, SIG_DFL, SA_SIGINFO ); // reset default signal handler 712 raise( SIGABRT ); // reraise SIGABRT 713 } // sigAbortHandler 714 715 static void initSignals() { 716 Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO ); 717 Signal( SIGBUS, sigSegvBusHandler, SA_SIGINFO ); 718 Signal( SIGFPE, sigFpeHandler, SA_SIGINFO ); 719 Signal( SIGABRT, sigAbortHandler, SA_SIGINFO ); 720 } 721 715 722 // Local Variables: // 716 723 // tab-width: 4 //
Note: See TracChangeset
for help on using the changeset viewer.