35         signal(SIGSEGV, CrashHandler::abortHandler);
 
   39         sa.sa_flags = SA_SIGINFO;
 
   40         sa.sa_sigaction = CrashHandler::abortHandler;
 
   41         sigemptyset( &sa.sa_mask );
 
   44         sigaction( SIGABRT, &sa, NULL );
 
   45         sigaction( SIGSEGV, &sa, NULL );
 
   46         sigaction( SIGBUS,  &sa, NULL );
 
   47         sigaction( SIGILL,  &sa, NULL );
 
   48         sigaction( SIGFPE,  &sa, NULL );
 
   49         sigaction( SIGPIPE, &sa, NULL );
 
   58 void CrashHandler::abortHandler(
int signum)
 
   61     const char* name = NULL;
 
   64         case SIGABRT: name = 
"SIGABRT";  
break;
 
   65         case SIGSEGV: name = 
"SIGSEGV";  
break;
 
   66         case SIGILL:  name = 
"SIGILL";   
break;
 
   67         case SIGFPE:  name = 
"SIGFPE";   
break;
 
   72         fprintf( stderr, 
"Caught signal %d (%s)\n", signum, name );
 
   74         fprintf( stderr, 
"Caught signal %d\n", signum );
 
   77     printStackTrace(stderr, 63);
 
   84 void CrashHandler::abortHandler( 
int signum, siginfo_t* si, 
void* unused )
 
   87     const char* name = NULL;
 
   90         case SIGABRT: name = 
"SIGABRT";  
break;
 
   91         case SIGSEGV: name = 
"SIGSEGV";  
break;
 
   92         case SIGBUS:  name = 
"SIGBUS";   
break;
 
   93         case SIGILL:  name = 
"SIGILL";   
break;
 
   94         case SIGFPE:  name = 
"SIGFPE";   
break;
 
   95         case SIGPIPE:  name = 
"SIGPIPE";   
break;
 
  100         fprintf( stderr, 
"Caught signal %d (%s)\n", signum, name );
 
  102         fprintf( stderr, 
"Caught signal %d\n", signum );
 
  105     printStackTrace(stderr, 63);
 
  112 void CrashHandler::printStackTrace(FILE *out, 
unsigned int max_frames)
 
  114     fprintf(out, 
"---- Unhandled Exception: Stack Trace ----\n");
 
  115     ZmqLogger::Instance()->LogToFile(
"---- Unhandled Exception: Stack Trace ----\n");
 
  116     stringstream stack_output;
 
  120     HANDLE process = GetCurrentProcess();
 
  121     HANDLE thread = GetCurrentThread();
 
  124     memset(&context, 0, 
sizeof(CONTEXT));
 
  125     context.ContextFlags = CONTEXT_FULL;
 
  126     RtlCaptureContext(&context);
 
  128     SymInitialize(process, NULL, TRUE);
 
  131     STACKFRAME64 stackframe;
 
  132     ZeroMemory(&stackframe, 
sizeof(STACKFRAME64));
 
  135     image = IMAGE_FILE_MACHINE_I386;
 
  136     stackframe.AddrPC.Offset = context.Eip;
 
  137     stackframe.AddrPC.Mode = AddrModeFlat;
 
  138     stackframe.AddrFrame.Offset = context.Ebp;
 
  139     stackframe.AddrFrame.Mode = AddrModeFlat;
 
  140     stackframe.AddrStack.Offset = context.Esp;
 
  141     stackframe.AddrStack.Mode = AddrModeFlat;
 
  143     image = IMAGE_FILE_MACHINE_AMD64;
 
  144     stackframe.AddrPC.Offset = context.Rip;
 
  145     stackframe.AddrPC.Mode = AddrModeFlat;
 
  146     stackframe.AddrFrame.Offset = context.Rsp;
 
  147     stackframe.AddrFrame.Mode = AddrModeFlat;
 
  148     stackframe.AddrStack.Offset = context.Rsp;
 
  149     stackframe.AddrStack.Mode = AddrModeFlat;
 
  151     image = IMAGE_FILE_MACHINE_IA64;
 
  152     stackframe.AddrPC.Offset = context.StIIP;
 
  153     stackframe.AddrPC.Mode = AddrModeFlat;
 
  154     stackframe.AddrFrame.Offset = context.IntSp;
 
  155     stackframe.AddrFrame.Mode = AddrModeFlat;
 
  156     stackframe.AddrBStore.Offset = context.RsBSP;
 
  157     stackframe.AddrBStore.Mode = AddrModeFlat;
 
  158     stackframe.AddrStack.Offset = context.IntSp;
 
  159     stackframe.AddrStack.Mode = AddrModeFlat;
 
  163     for (
size_t i = 0; i < max_frames; i++) {
 
  165         BOOL result = StackWalk64(
 
  166                 image, process, thread,
 
  167                 &stackframe, &context, NULL,
 
  168                 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
 
  170         if (i <= 2) { 
continue; } 
 
  171         if (!result) { 
break; }
 
  173         char buffer[
sizeof(SYMBOL_INFO) + MAX_SYM_NAME * 
sizeof(TCHAR)];
 
  174         PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
 
  175         symbol->SizeOfStruct = 
sizeof(SYMBOL_INFO);
 
  176         symbol->MaxNameLen = MAX_SYM_NAME;
 
  177         WINBOOL found_symbol = SymFromAddr(process, stackframe.AddrPC.Offset, NULL, symbol);
 
  180             printf(
"[%i] %s, address 0x%0X\n", i, symbol->Name, symbol->Address);
 
  181             stack_output << left << setw(30) << symbol->Name << 
" " << setw(40) << std::hex << symbol->Address << std::dec << endl;
 
  183             printf(
"[%i] ???\n", i);
 
  184             stack_output << left << setw(30) << 
"???" << endl;
 
  192     void* addrlist[max_frames+1];
 
  195     unsigned int addrlen = backtrace( addrlist, 
sizeof( addrlist ) / 
sizeof( 
void* ));
 
  199         fprintf(out, 
"  No stack trace found (addrlen == 0)\n");
 
  200         ZmqLogger::Instance()->LogToFile(
"  No stack trace found (addrlen == 0)\n");
 
  207     char** symbollist = backtrace_symbols( addrlist, addrlen );
 
  209     size_t funcnamesize = 1024;
 
  214     for ( 
unsigned int i = 4; i < addrlen; i++ )
 
  216         char* begin_name   = NULL;
 
  217         char* begin_offset = NULL;
 
  218         char* end_offset   = NULL;
 
  223       for ( 
char *p = symbollist[i]; *p; ++p )
 
  225          if (( *p == 
'_' ) && ( *(p-1) == 
' ' ))
 
  227          else if ( *p == 
'+' )
 
  231       if ( begin_name && begin_offset && ( begin_name < begin_offset ))
 
  233          *begin_name++ = 
'\0';
 
  234          *begin_offset++ = 
'\0';
 
  240          char* ret = abi::__cxa_demangle( begin_name, &funcname[0], &funcnamesize, &status );
 
  244             fprintf( out, 
"  %-30s %-40s %s\n", symbollist[i], funcname, begin_offset );
 
  245             stack_output << left << 
" " << setw(30) << symbollist[i] << 
" " << setw(40) << funcname << 
" " << begin_offset << endl;
 
  249             fprintf( out, 
"  %-30s %-38s() %s\n", symbollist[i], begin_name, begin_offset );
 
  250             stack_output << left << 
"  " << setw(30) << symbollist[i] << 
" " << setw(38) << begin_name << 
" " << begin_offset << endl;
 
  253 #else // !DARWIN - but is posix 
  256         for ( 
char *p = symbollist[i]; *p; ++p )
 
  260             else if ( *p == 
'+' )
 
  262             else if ( *p == 
')' && ( begin_offset || begin_name ))
 
  266         if ( begin_name && end_offset && ( begin_name < end_offset ))
 
  268             *begin_name++   = 
'\0';
 
  269             *end_offset++   = 
'\0';
 
  271                 *begin_offset++ = 
'\0';
 
  277             char* ret = abi::__cxa_demangle( begin_name, funcname, &funcnamesize, &status );
 
  278             char* fname = begin_name;
 
  284                 fprintf( out, 
"  %-30s ( %-40s  + %-6s) %s\n", symbollist[i], fname, begin_offset, end_offset );
 
  285                 stack_output << left << 
"  " << setw(30) << symbollist[i] << 
" " << setw(40) << fname << 
" " << begin_offset << 
" " << end_offset << endl;
 
  288                 fprintf( out, 
"  %-30s ( %-40s    %-6s) %s\n", symbollist[i], fname, 
"", end_offset );
 
  289                 stack_output << left << 
"  " << setw(30) << symbollist[i] << 
" " << setw(40) << fname << 
" " << end_offset << endl;
 
  292 #endif  // !DARWIN - but is posix 
  295             fprintf(out, 
"  %-40s\n", symbollist[i]);
 
  296             stack_output << left << 
"  " << setw(40) << symbollist[i] << endl;
 
  305     ZmqLogger::Instance()->LogToFile(stack_output.str());
 
  307     fprintf(out, 
"---- End of Stack Trace ----\n");
 
  308     ZmqLogger::Instance()->LogToFile(
"---- End of Stack Trace ----\n");