void Write (QtMsgType type, const char *message, DebugWriteFlags flags) { #if !defined (Q_OS_WIN32) if (!strcmp (message, "QPixmap::handle(): Pixmap is not an X11 class pixmap") || strstr (message, ": Painter not active")) return; #endif #if defined (Q_OS_WIN32) if (!strcmp (message, "QObject::startTimer: QTimer can only be used with threads started with QThread")) return; #endif QMutexLocker locker { &G_DbgMutex }; const auto& ostr = GetOstream (type, flags); *ostr << "[" << QDateTime::currentDateTime ().toString ("dd.MM.yyyy HH:mm:ss.zzz").toStdString () << "] [" << QThread::currentThread () << "] [" << std::setfill ('0') << std::setw (3) << Counter++ << "] " << message << std::endl; if (type != QtDebugMsg && (flags & DWFBacktrace)) PrintBacktrace (ostr); }
/* * Signal handler */ void SignalProc(int signum) { switch (signum) { case SIGINT: signal(SIGINT, SIG_DFL); // Reset the signal handler ExitProc(); break; case SIGTERM: signal(SIGTERM, SIG_DFL); // Reset the signal handler ExitProc(); break; case SIGCHLD: // ignoring break; #ifdef DEBUG case SIGSEGV: signal(SIGSEGV, SIG_DFL); // Reset the signal handler PrintBacktrace(); break; #endif } }
void PrintStackBacktrace() { CONTEXT context; ZeroMemory(&context, sizeof(CONTEXT)); RtlCaptureContext(&context); PrintBacktrace(&context); }
void ExeStop( const char* MsgCStr, const char* ReasonCStr, const char* CondCStr, const char* FNm, const int& LnN) { char ReasonMsgCStr[1000]; #if SW_TRACE PrintBacktrace(); Crash(); #endif // construct reason message if (ReasonCStr==NULL) { ReasonMsgCStr[0]=0; } else { sprintf(ReasonMsgCStr, " [Reason:'%s']", ReasonCStr); } // construct full message char FullMsgCStr[1000]; if (MsgCStr==NULL) { if (CondCStr==NULL) { sprintf(FullMsgCStr, "Execution stopped%s!", ReasonMsgCStr); } else { sprintf(FullMsgCStr, "Execution stopped: %s%s, file %s, line %d", CondCStr, ReasonMsgCStr, FNm, LnN); } } else { if (CondCStr==NULL) { sprintf(FullMsgCStr, "%s\nExecution stopped!", MsgCStr); } else { sprintf(FullMsgCStr, "Message: %s%s\nExecution stopped: %s, file %s, line %d", MsgCStr, ReasonMsgCStr, CondCStr, FNm, LnN); } } // report full message to log file SaveToErrLog(FullMsgCStr); #if defined(SW_NOABORT) TExcept::Throw(FullMsgCStr); #endif // report to screen & stop execution bool Continue=false; // call handler if (TOnExeStop::IsOnExeStopF()) { Continue=!((*TOnExeStop::GetOnExeStopF())(FullMsgCStr)); } if (!Continue) { ErrNotify(FullMsgCStr); #ifdef GLib_WIN32 abort(); //ExitProcess(1); #else exit(1); #endif } }
void ReportBacktrace() { static const int framesToShow = 31; static const int framesToSkip = 2; void* samples[framesToShow + framesToSkip]; int frames = framesToShow + framesToSkip; GetBacktrace(samples, &frames); PrintBacktrace(samples + framesToSkip, frames - framesToSkip); }
LONG __stdcall ExceptionFilter(EXCEPTION_POINTERS* exPtrs) { error("Unhandled Exception: code: 0x%8.8X, flags: %d, address: 0x%8.8X", exPtrs->ExceptionRecord->ExceptionCode, exPtrs->ExceptionRecord->ExceptionFlags, exPtrs->ExceptionRecord->ExceptionAddress); #ifdef DEBUG PrintBacktrace(exPtrs->ContextRecord); #else info("Detailed exception information can be printed by debug version of NZBGet (available from download page)"); #endif ExitProcess(-1); return EXCEPTION_CONTINUE_SEARCH; }
void boinc_catch_signal(int signal) { switch(signal) { case SIGHUP: fprintf(stderr, "SIGHUP: terminal line hangup\n"); return; case SIGINT: fprintf(stderr, "SIGINT: interrupt program\n"); break; case SIGILL: fprintf(stderr, "SIGILL: illegal instruction\n"); break; case SIGABRT: fprintf(stderr, "SIGABRT: abort called\n"); break; #if SIGBUS != SIGSEGV // in case SIGBUS == SIGSEGV (e.g., Haiku) case SIGBUS: fprintf(stderr, "SIGBUS: bus error\n"); break; #endif case SIGSEGV: fprintf(stderr, "SIGSEGV: segmentation violation\n"); break; case SIGSYS: fprintf(stderr, "SIGSYS: system call given invalid argument\n"); break; case SIGPIPE: fprintf(stderr, "SIGPIPE: write on a pipe with no reader\n"); return; default: fprintf(stderr, "unknown signal %d\n", signal); break; } #ifdef __GLIBC__ void *array[64]; size_t size; size = backtrace (array, 64); // Anything that calls malloc here (i.e *printf()) will probably fail // so we'll do it the hard way. write(fileno(stderr),"Stack trace (",strlen("Stack trace (")); char mbuf[10]; char *p=mbuf+9; int i=size; *(p--)=0; while (i) { *(p--)=i%10+'0'; i/=10; } write(fileno(stderr),p+1,strlen(p+1)); write(fileno(stderr)," frames):",strlen(" frames):")); mbuf[0]=10; write(fileno(stderr),mbuf,1); backtrace_symbols_fd(array, size, fileno(stderr)); #endif #ifdef __APPLE__ PrintBacktrace(); #endif fprintf(stderr, "\nExiting...\n"); _exit(signal_exit_code); }
void boinc_catch_signal(int signal, struct siginfo *siginfo, void *sigcontext) { #else void boinc_catch_signal(int signal) { #endif switch(signal) { case SIGHUP: fprintf(stderr, "SIGHUP: terminal line hangup\n"); return; case SIGINT: fprintf(stderr, "SIGINT: interrupt program\n"); break; case SIGILL: fprintf(stderr, "SIGILL: illegal instruction\n"); break; case SIGABRT: fprintf(stderr, "SIGABRT: abort called\n"); break; #if SIGBUS != SIGSEGV // in case SIGBUS == SIGSEGV (e.g., Haiku) case SIGBUS: fprintf(stderr, "SIGBUS: bus error\n"); break; #endif case SIGSEGV: fprintf(stderr, "SIGSEGV: segmentation violation\n"); break; case SIGSYS: fprintf(stderr, "SIGSYS: system call given invalid argument\n"); break; case SIGPIPE: fprintf(stderr, "SIGPIPE: write on a pipe with no reader\n"); return; default: fprintf(stderr, "unknown signal %d\n", signal); break; } #ifdef __GLIBC__ void *array[64]; size_t size; size = backtrace (array, 64); // Anything that calls malloc here (i.e *printf()) will probably fail // so we'll do it the hard way. (void) write(fileno(stderr),"Stack trace (",strlen("Stack trace (")); char mbuf[10]; char *p=mbuf+9; int i=size; *(p--)=0; while (i) { *(p--)=i%10+'0'; i/=10; } (void) write(fileno(stderr),p+1,strlen(p+1)); (void) write(fileno(stderr)," frames):",strlen(" frames):")); mbuf[0]=10; (void) write(fileno(stderr),mbuf,1); backtrace_symbols_fd(array, size, fileno(stderr)); #endif #ifdef __APPLE__ PrintBacktrace(); #endif #ifdef ANDROID // this is some dark undocumented Android voodoo that uses libcorkscrew.so // minimal use of library functions because they may not work in an signal // handler. #define DUMP_LINE_LEN 256 static backtrace_frame_t backtrace[64]; static backtrace_symbol_t backtrace_symbols[64]; if (unwind_backtrace_signal_arch != NULL) { map_info_t *map_info=acquire_my_map_info_list(); ssize_t size=unwind_backtrace_signal_arch(siginfo,sigcontext,map_info,backtrace,0,64); get_backtrace_symbols(backtrace,size,backtrace_symbols); char line[DUMP_LINE_LEN]; for (int i=0;i<size;i++) { format_backtrace_line(i,&backtrace[i],&backtrace_symbols[i],line,DUMP_LINE_LEN); line[DUMP_LINE_LEN-1]=0; if (backtrace_symbols[i].symbol_name) { strlcat(line," ",DUMP_LINE_LEN); if (backtrace_symbols[i].demangled_name) { strlcat(line,backtrace_symbols[i].demangled_name,DUMP_LINE_LEN); } } else { symbol_table_t* symbols = NULL; if (backtrace_symbols[i].map_name) { symbols = load_symbol_table(backtrace_symbols[i].map_name); } else { symbols = load_symbol_table(argv0); } symbol_t* symbol = NULL; if (symbols) { symbol = find_symbol(symbols, backtrace[i].absolute_pc); } if (symbol) { int offset = backtrace[i].absolute_pc - symbol->start; strlcat(line," (",DUMP_LINE_LEN); strlcat(line,symbol->name,DUMP_LINE_LEN); strlcat(line,"+",DUMP_LINE_LEN); strlcat(line,xtoa(offset),DUMP_LINE_LEN); strlcat(line,")",DUMP_LINE_LEN); line[DUMP_LINE_LEN-1]=0; } else { strlcat(line, " (\?\?\?)",DUMP_LINE_LEN); } if (symbols) free_symbol_table(symbols); } if (backtrace[i].absolute_pc) { strlcat(line," [",DUMP_LINE_LEN); strlcat(line,xtoa(*reinterpret_cast<unsigned int *>(backtrace[i].absolute_pc)),DUMP_LINE_LEN); strlcat(line,"]",DUMP_LINE_LEN); } strlcat(line,"\n",DUMP_LINE_LEN); write(fileno(stderr),line,strlen(line)); fflush(stderr); } } #endif // ANDROID fprintf(stderr, "\nExiting...\n"); _exit(signal_exit_code); } #endif // // Diagnostics Routines common to all Platforms // // Converts the BOINCTRACE macro into a single string and report it // to the CRT so it can be reported via the normal means. // void boinc_trace(const char *pszFormat, ...) { static char szBuffer[4096]; static char szDate[64]; static char szTime[64]; int n; // Trace messages should only be reported if running as a standalone // application or told too. if ((flags & BOINC_DIAG_TRACETOSTDERR) || (flags & BOINC_DIAG_TRACETOSTDOUT)) { memset(szBuffer, 0, sizeof(szBuffer)); memset(szDate, 0, sizeof(szDate)); memset(szTime, 0, sizeof(szTime)); #ifdef _WIN32 strdate(szDate); strtime(szTime); #else time_t t; char *theCR; time(&t); safe_strcpy(szTime, asctime(localtime(&t))); theCR = strrchr(szTime, '\n'); if (theCR) *theCR = '\0'; theCR = strrchr(szTime, '\r'); if (theCR) *theCR = '\0'; #endif va_list ptr; va_start(ptr, pszFormat); vsnprintf(szBuffer, sizeof(szBuffer), pszFormat, ptr); va_end(ptr); #if defined(_WIN32) && defined(_DEBUG) n = _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "[%s %s] TRACE [%d]: %s", szDate, szTime, GetCurrentThreadId(), szBuffer); #else if (flags & BOINC_DIAG_TRACETOSTDERR) { #ifdef _WIN32 n = fprintf(stderr, "[%s %s] TRACE [%d]: %s\n", szDate, szTime, GetCurrentThreadId(), szBuffer); #else n = fprintf(stderr, "[%s] TRACE: %s\n", szTime, szBuffer); #endif if (n > 0) stderr_file_size += n; } if (flags & BOINC_DIAG_TRACETOSTDOUT) { #ifdef _WIN32 n = fprintf(stdout, "[%s %s] TRACE [%d]: %s\n", szDate, szTime, GetCurrentThreadId(), szBuffer); #else n = fprintf(stdout, "[%s] TRACE: %s\n", szTime, szBuffer); #endif if (n > 0) stdout_file_size += n; } #endif } } // Converts the BOINCINFO macro into a single string and report it // to stderr so it can be reported via the normal means. // #ifndef BOINC_INFOMSGS void boinc_info(const char* /*pszFormat*/, ... ){ return; } #else void boinc_info(const char* pszFormat, ...){ static char szBuffer[4096]; static char szDate[64]; static char szTime[64]; int n; memset(szBuffer, 0, sizeof(szBuffer)); memset(szDate, 0, sizeof(szDate)); memset(szTime, 0, sizeof(szTime)); strdate(szDate); strtime(szTime); va_list ptr; va_start(ptr, pszFormat); vsnprintf(szBuffer, sizeof(szBuffer), pszFormat, ptr); va_end(ptr); #if defined(_WIN32) && defined(_DEBUG) _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "[%s %s] BOINCMSG: %s\n", szDate, szTime, szBuffer); #else if (flags & BOINC_DIAG_TRACETOSTDERR) { n = fprintf(stderr, "[%s %s] BOINCMSG: %s\n", szDate, szTime, szBuffer); if (n > 0) stderr_file_size += n; } if (flags & BOINC_DIAG_TRACETOSTDOUT) { n = fprintf(stdout, "[%s %s] BOINCMSG: %s\n", szDate, szTime, szBuffer); if (n > 0) stdout_file_size += n; } #endif } #endif void diagnostics_set_max_file_sizes(int stdout_size, int stderr_size) { if (stdout_size) max_stdout_file_size = stdout_size; if (stderr_size) max_stderr_file_size = stderr_size; } // Dump string to whatever the platform debuggers // #ifndef _WIN32 int diagnostics_trace_to_debugger(const char*) { return 0; }