/** * Logs the details of this crash and shows an error. * @param ex Pointer to exception data (PEXCEPTION_POINTERS on Windows, signal int on Unix) * @param err Exception message, if any. */ void crashDump(void *ex, const std::string &err) { std::ostringstream error; #ifdef _WIN32 PEXCEPTION_POINTERS exception = (PEXCEPTION_POINTERS)ex; if (exception->ExceptionRecord->ExceptionCode == EXCEPTION_CODE_CXX) { std::exception *cppException = (std::exception *)exception->ExceptionRecord->ExceptionInformation[1]; error << cppException->what(); } else { error << "code 0x" << std::hex << exception->ExceptionRecord->ExceptionCode; } Log(LOG_FATAL) << "A fatal error has occurred: " << error.str(); stackTrace(exception->ContextRecord); std::string dumpName = Options::getUserFolder(); dumpName += now() + ".dmp"; HANDLE dumpFile = CreateFileA(dumpName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); MINIDUMP_EXCEPTION_INFORMATION exceptionInformation; exceptionInformation.ThreadId = GetCurrentThreadId(); exceptionInformation.ExceptionPointers = exception; exceptionInformation.ClientPointers = FALSE; if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, MiniDumpNormal, exception ? &exceptionInformation : NULL, NULL, NULL)) { Log(LOG_FATAL) << "Crash dump generated at " << dumpName; } else { Log(LOG_FATAL) << "No crash dump generated: " << GetLastError(); } #else if (ex == 0) { error << err; } else { int signal = *((int*)ex); error << "signal " << signal; } Log(LOG_FATAL) << "A fatal error has occurred: " << error.str(); stackTrace(0); #endif std::ostringstream msg; msg << "OpenXcom has crashed: " << error.str() << std::endl; msg << "Extra information has been saved to openxcom.log." << std::endl; msg << "If this error was unexpected, please report it to the developers."; showError(msg.str()); }
void SampleNode::add(const memprof::sample& sample, size_t frame) { StackTrace stackTrace(sample.getStackTrace()); StackFrames stackFrames(stackTrace.getFrames()); add(stackFrames, sample.getAllocatedBytes(), frame); }
void Runtime::runMainScript() { v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Handle<v8::Context> context = v8::Context::New( v8::Isolate::GetCurrent()); v8::Context::Scope contextScope(context); m_sip = new JsSIPObject(m_sipFactory); m_sip->createObjectInstance(context->Global(), "sip"); v8::TryCatch tryCatch; std::string mainScript; loadMainScript(mainScript); v8::Handle<v8::Script> script = v8::Script::Compile( v8::String::New(mainScript.c_str()), v8::String::New(m_scriptFileName.c_str())); if (script.IsEmpty()) { throw Exception(JsProxyBase::toString(tryCatch.Exception()).c_str()); } v8::Handle<v8::Value> result = script->Run(); if (result.IsEmpty()) { // TODO: add log v8::String::Utf8Value stackTrace(tryCatch.StackTrace()); if (stackTrace.length() > 0) { throw Exception(*stackTrace); } throw Exception(JsProxyBase::toString(tryCatch.Exception()).c_str()); } }
PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed) { if (!v8::Context::InContext()) return 0; v8::HandleScope handleScope; v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(maxStackSize, stackTraceOptions)); return createScriptCallStack(stackTrace, maxStackSize, emptyStackIsAllowed); }
PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); if (!isolate->InContext()) return nullptr; v8::HandleScope handleScope(isolate); v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, stackTraceOptions)); return createScriptCallStack(stackTrace, maxStackSize, emptyStackIsAllowed, isolate); }
// -------------------------------------------------------------------------- QDebug ctkException::printStackTrace(QDebug dbg) const { QSet<const ctkException*> dejaVu; dejaVu.insert(this); // Print our stack trace dbg.nospace() << this->what() << '\n'; QList<QString> trace = stackTrace(); foreach(QString traceElement, trace) { dbg.nospace() << "\tat " << qPrintable(traceElement) << '\n'; }
inline void stackTraceOn(Signal s) { #ifndef _WIN32 signal(s, [](int sig) { { std::lock_guard<std::mutex> lock(mutex); std::cout << "Got error " << sig << std::endl; } stackTrace(); exit(1); }); #endif }
// from: https://github.com/v8/v8-git-mirror/blob/master/samples/shell.cc // v3.15 from: https://chromium.googlesource.com/v8/v8.git/+/3.14.5.9/samples/shell.cc void reportException(v8::TryCatch* _tryCatch) { v8::HandleScope handle_scope; v8::String::Utf8Value exception(_tryCatch->Exception()); char const* exceptionString = toCString(exception); v8::Handle<v8::Message> message = _tryCatch->Message(); // V8 didn't provide any extra information about this error; just // print the exception. if (message.IsEmpty()) printf("%s\n", exceptionString); else { // Print (filename):(line number): (message). v8::String::Utf8Value filename(message->GetScriptResourceName()); char const* filenameString = toCString(filename); int linenum = message->GetLineNumber(); printf("%s:%i: %s\n", filenameString, linenum, exceptionString); // Print line of source code. v8::String::Utf8Value sourceline(message->GetSourceLine()); char const* sourcelineString = toCString(sourceline); printf("%s\n", sourcelineString); // Print wavy underline (GetUnderline is deprecated). int start = message->GetStartColumn(); for (int i = 0; i < start; i++) printf(" "); int end = message->GetEndColumn(); for (int i = start; i < end; i++) printf("^"); printf("\n"); v8::String::Utf8Value stackTrace(_tryCatch->StackTrace()); if (stackTrace.length() > 0) { char const* stackTraceString = toCString(stackTrace); printf("%s\n", stackTraceString); } } }
static void dumpStack(const char* msg, bool throwException) { try { ScopedLock lock(btDumpMutex); #define FILE_NAME_LEN (128) char logfileName[FILE_NAME_LEN] = {0}; char curTime[DATETIME_LEN] = {0}; base::TimeUtil::format(curTime, DATETIME_LEN, "%Y%m%d-%H%M%S"); bfs::path p = sLogConfigure.baseDir(); snprintf(logfileName, FILE_NAME_LEN, "%s.%d.%s.%s.log", sLogConfigure.invocationShortName().c_str(), getpid(), "dump", curTime); p /= logfileName; #undef FILE_NAME_LEN bfs::fstream ss(p, std::ios_base::app); ss << msg; stackTrace(ss); ss.close(); int32_t level = throwException ? LOG_LEVEL_FATAL : LOG_LEVEL_ERROR; if( sLogConfigure.isLogToStderr(level) ) { coloredWriteToStderr(level, msg, strlen(msg)); coloredWriteToStderr(level, "\n",strlen("\n")); } } catch(...) { } if(throwException) throw 1; }
// Slight modification to an original function found in the V8 sample shell.cc. void Global::reportException(TryCatch* tryCatch) { HandleScope handleScope(fIsolate); String::Utf8Value exception(tryCatch->Exception()); const char* exceptionString = to_cstring(exception); Handle<Message> message = tryCatch->Message(); if (message.IsEmpty()) { // V8 didn't provide any extra information about this error; just // print the exception. fprintf(stderr, "%s\n", exceptionString); } else { // Print (filename):(line number): (message). String::Utf8Value filename(message->GetScriptOrigin().ResourceName()); const char* filenameString = to_cstring(filename); int linenum = message->GetLineNumber(); fprintf(stderr, "%s:%i: %s\n", filenameString, linenum, exceptionString); // Print line of source code. String::Utf8Value sourceline(message->GetSourceLine()); const char* sourceLineString = to_cstring(sourceline); fprintf(stderr, "%s\n", sourceLineString); // Print wavy underline. int start = message->GetStartColumn(); for (int i = 0; i < start; i++) { fprintf(stderr, " "); } int end = message->GetEndColumn(); for (int i = start; i < end; i++) { fprintf(stderr, "^"); } fprintf(stderr, "\n"); String::Utf8Value stackTrace(tryCatch->StackTrace()); if (stackTrace.length() > 0) { const char* stackTraceString = to_cstring(stackTrace); fprintf(stderr, "%s\n", stackTraceString); } } }
void PromiseTracker::didReceiveV8PromiseEvent(ScriptState* scriptState, v8::Handle<v8::Object> promise, v8::Handle<v8::Value> parentPromise, int status) { ASSERT(isEnabled()); int promiseHash = promise->GetIdentityHash(); PromiseDataVector* vector; PromiseDataMap::iterator it = m_promiseDataMap.find(promiseHash); if (it != m_promiseDataMap.end()) vector = &it->value; else vector = &m_promiseDataMap.add(promiseHash, PromiseDataVector()).storedValue->value; v8::Isolate* isolate = scriptState->isolate(); RefPtr<PromiseData> data; int index = indexOf(vector, ScopedPersistent<v8::Object>(isolate, promise)); if (index == -1) { data = adoptRef(new PromiseData(isolate, promiseHash, promise)); OwnPtr<PromiseDataWrapper> wrapper = adoptPtr(new PromiseDataWrapper(data->m_weakPtrFactory.createWeakPtr(), &m_promiseDataMap)); data->m_promise.setWeak(wrapper.leakPtr(), &PromiseDataWrapper::didRemovePromise); vector->append(data); } else { data = vector->at(index); } if (!parentPromise.IsEmpty()) { ASSERT(parentPromise->IsObject()); data->m_parentPromise.set(isolate, parentPromise->ToObject()); } else { data->m_status = status; if (!status) { v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(isolate, 1)); RefPtr<ScriptCallStack> stack = createScriptCallStack(stackTrace, 1, isolate); if (stack->size()) data->m_callFrame = stack->at(0); } } }
static DebugWaitFor dbgStackTrace(char *line, processPo p, termPo loc, insWord ins, void *cl) { stackTrace(p, debugOutChnnl, (logical) (cl)); resetDeflt("n"); return moreDebug; }
int main( int argc, char *argv[] ) { if ( argc < 2 ) { std::cout << "QGIS Crash Handler Usage: \n" << "qgiscrashhandler {infofile}" << std::endl; return -1; } QApplication app( argc, argv ); app.setQuitOnLastWindowClosed( true ); QCoreApplication::setOrganizationName( "QGIS" ); QCoreApplication::setApplicationName( "QGIS3" ); QString extraInfoFile = QString( argv[1] ); std::cout << "Extra Info File: " << extraInfoFile.toUtf8().data() << std::endl; QFile file( extraInfoFile ); QString processIdString; QString threadIdString; QString exceptionPointersString; QString symbolPaths; QString reloadArgs; QStringList versionInfo; if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) { processIdString = file.readLine(); threadIdString = file.readLine(); exceptionPointersString = file.readLine(); symbolPaths = file.readLine(); reloadArgs = file.readLine(); // The version info is the last stuff to be in the file until the end // bit gross but :) QString info = file.readAll(); versionInfo = info.split( "\n" ); } DWORD processId; DWORD threadId; LPEXCEPTION_POINTERS exception; processId = processIdString.toULong(); threadId = threadIdString.toULong(); sscanf_s( exceptionPointersString.toLocal8Bit().constData(), "%p", &exception ); std::cout << "Process ID: " << processIdString.toLocal8Bit().constData() << std::endl; std::cout << "Thread ID:" << threadIdString.toLocal8Bit().constData() << std::endl; std::cout << "Exception Pointer: " << exceptionPointersString.toLocal8Bit().constData() << std::endl; std::cout << "Symbol Path :" << symbolPaths.toUtf8().data() << std::endl; std::unique_ptr<QgsStackTrace> stackTrace( QgsStackTrace::trace( processId, threadId, exception, symbolPaths ) ); QgsCrashReport report; report.setVersionInfo( versionInfo ); report.setStackTrace( stackTrace.get() ); report.exportToCrashFolder(); QgsCrashDialog dlg; dlg.setReloadArgs( reloadArgs ); dlg.setBugReport( report.toHtml() ); dlg.setModal( true ); dlg.show(); app.exec(); for ( HANDLE threadHandle : stackTrace->threads ) { ResumeThread( threadHandle ); CloseHandle( threadHandle ); } CloseHandle( stackTrace->process ); return 0; }
void debugKernel(Regs *regs) { Thread *thread = getCurrentThread(); if (thread != NULL) { fpuSave(&thread->fpuRegs); memcpy(&thread->regs, regs, sizeof(Regs)); }; while (1) { kprintf_debug("RAX=0 - panic and stop\n"); kprintf_debug("RAX=1 - show stack trace\n"); kprintf_debug("RAX=2 - dump runqueue\n"); kprintf_debug("RAX=3 - dump module list\n"); kprintf_debug("RAX=4 - switch to a different process\n"); kprintf_debug("RAX=5 - dump current context\n"); kprintf_debug("RAX=6 - dump memory mappings\n"); kprintf_debug("RAX=7 - show semaphore state\n"); kprintf_debug("RAX=8 - debug the current context in bochs\n"); kprintf_debug("RAX=9 - show stack trace of interrupted state\n"); uint64_t option = getDebugInput(); switch (option) { case 0: panic("Kernel died"); break; case 1: stackTrace(getCurrentThread()->regs.rip, getCurrentThread()->regs.rbp); break; case 2: dumpRunqueue(); break; case 3: dumpModules(); break; case 4: kprintf_debug(" *** PLEASE SET RAX TO INDEX ***\n"); switchTaskToIndex((int)getDebugInput()); break; case 5: kprintf("PID: %d, '%s'\n", getCurrentThread()->pid, getCurrentThread()->name); kprintf("WAKE: %d, TICKS: %d\n", (int) getCurrentThread()->wakeTime, getUptime()); kdumpregs(&getCurrentThread()->regs); break; case 6: kprintf("PID: %d, '%s'\n", getCurrentThread()->pid, getCurrentThread()->name); if (getCurrentThread()->pm == NULL) { kprintf("This thread has no memory\n"); break; }; kprintf(" *** YOU MAY SPECIFY AN ADDRESS TO CHECK FOR IN RAX ***\n"); dumpProcessMemory(getCurrentThread()->pm, getDebugInput()); break; case 7: kprintf(" *** SET RAX TO SEMAPHORE ADDRESS ***\n"); semDump((Semaphore*)getDebugInput()); break; case 8: getCurrentThread()->regs.rflags &= ~(1 << 9); // cli enterDebugContext(&getCurrentThread()->regs); break; case 9: stackTrace(regs->rip, regs->rbp); break; }; }; };