void BankMaintainer::printTrace() { std::ifstream traceFile("trace.txt"); std::string currentLine; if (traceFile.is_open()) { while (std::getline(traceFile, currentLine)) { std::cout << currentLine << std::endl; } } traceFile.close(); }
DBGSERV_API const TraceService& TraceService::operator << (LPCSTR lpcstr) const { const CHAR* szSourceFileName = GetSourceFileName(); int nCodeLineNumber = GetCodeLineNumber(); #ifdef _DEBUG // Always use the OutputDebugString in debug version. if (nCodeLineNumber != 0) { std::ostringstream outputStream; outputStream << szSourceFileName << "(" << nCodeLineNumber << ") "; ::OutputDebugStringA(outputStream.str().c_str()); if (!m_bLogEnabled) { nCodeLineNumber = 0; SetCodeLineNumber(0); } } ::OutputDebugStringA(lpcstr); #endif if (m_bLogEnabled) { // Compute the trace file name. The name includes the thread id. There will be // on tace log file per thread. std::ostringstream oFileNameStream; oFileNameStream << m_sLogFile << ::GetCurrentThreadId() << ".txt"; // Open the log file. Log file is always ASCII. std::ofstream traceFile(oFileNameStream.str().c_str(), std::ios_base::app); if (traceFile.is_open()) { if (nCodeLineNumber != 0) { traceFile << szSourceFileName << "(" << nCodeLineNumber << ") "; } traceFile << lpcstr; traceFile.close(); } SetCodeLineNumber(0); } return *this; }
//-------------------------------------------------------------------------- /// Load a trace file from disk when given a valid path. /// \param inTraceFilepath The full filepath to a trace file. /// \param outTraceFileContents The full contents of the loaded trace file. /// \returns True if the trace file was loaded correctly. //-------------------------------------------------------------------------- bool MultithreadedTraceAnalyzerLayer::LoadTraceFile(const std::string& inTraceFilepath, gtASCIIString& outTraceFileContents) { bool bReadSuccessful = false; gtString traceFilepath; traceFilepath.fromASCIIString(inTraceFilepath.c_str()); osFile traceFile(traceFilepath); bool bTraceFileOpened = traceFile.open(osChannel::OS_ASCII_TEXT_CHANNEL); if (bTraceFileOpened) { // Read the entire file and return the contents through the output string. if (traceFile.readIntoString(outTraceFileContents)) { bReadSuccessful = true; } else { Log(logERROR, "Failed to read trace file at path '%s'.", inTraceFilepath.c_str()); } } return bReadSuccessful; }
void TbTraceTool::flatTrace() { PathBuilder pb(&m_parser); m_parser.parse(TraceFiles); ModuleCache mc(&pb); TestCase tc(&pb); PathSet paths; pb.getPaths(paths); cl::list<unsigned>::const_iterator listit; if (PathList.empty()) { PathSet::iterator pit; for (pit = paths.begin(); pit != paths.end(); ++pit) { PathList.push_back(*pit); } } //XXX: this is efficient only for short paths or for a small number of //path, because complexity is O(n2): we reprocess the prefixes. for(listit = PathList.begin(); listit != PathList.end(); ++listit) { std::cout << "Processing path " << std::dec << *listit << std::endl; PathSet::iterator pit = paths.find(*listit); if (pit == paths.end()) { std::cerr << "Could not find path with id " << std::dec << *listit << " in the execution trace." << std::endl; continue; } std::stringstream ss; ss << LogDir << "/" << *listit << ".txt"; std::ofstream traceFile(ss.str().c_str()); TbTrace trace(&m_binaries, &mc, &pb, traceFile); if (!pb.processPath(*listit)) { std::cerr << "Could not process path " << std::dec << *listit << std::endl; continue; } traceFile << "----------------------" << std::endl; if (trace.hasDebugInfo() == false) { traceFile << "WARNING: No debug information for any module in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure you have set the module path properly and the binaries contain debug information." << std::endl << std::endl; } if (trace.hasModuleInfo() == false) { traceFile << "WARNING: No module information for any module in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the ModuleTracer plugin before running this tool." << std::endl << std::endl; } if (trace.hasItems() == false ) { traceFile << "WARNING: No basic blocks in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the TranslationBlockTracer plugin before running this tool. " << std::endl << std::endl; } TestCaseState *tcs = static_cast<TestCaseState*>(pb.getState(&tc, *pit)); if (!tcs) { traceFile << "WARNING: No test case in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the TestCaseGenerator plugin and terminate the states before running this tool. " << std::endl << std::endl; }else { tcs->printInputs(traceFile); } } }
bool ErrorReport::getCrashDescription() { #ifdef HAVE_WINAPI return true; #else // !defined(HAVE_WINAPI) switch(m_pCrashInfo->signal) { case SIGILL: { m_ReportDescription = "Illegal instruction"; switch(m_pCrashInfo->code) { #ifdef ILL_ILLOPC case ILL_ILLOPC: m_ReportDescription += ": illegal opcode"; break; #endif #ifdef ILL_ILLOPN case ILL_ILLOPN: m_ReportDescription += ": illegal operand"; break; #endif #ifdef ILL_ADR case ILL_ADR: m_ReportDescription += ": illegal addressing mode"; break; #endif #ifdef ILL_ILLTRP case ILL_ILLTRP: m_ReportDescription += ": illegal trap"; break; #endif #ifdef ILL_PRVOPC case ILL_PRVOPC: m_ReportDescription += ": privileged opcode"; break; #endif #ifdef ILL_PRVREG case ILL_PRVREG: m_ReportDescription += ": privileged register"; break; #endif #ifdef ILL_COPROC case ILL_COPROC: m_ReportDescription += ": coprocessor error"; break; #endif #ifdef ILL_BADSTK case ILL_BADSTK: m_ReportDescription += ": internal stack error"; break; #endif default: break; } break; } case SIGABRT: { m_ReportDescription = "Abnormal termination"; break; } case SIGBUS: { m_ReportDescription = "Bus error"; switch(m_pCrashInfo->code) { #ifdef BUS_ADRALN case BUS_ADRALN: m_ReportDescription += ": invalid address alignment"; break; #endif #ifdef BUS_ADRERR case BUS_ADRERR: m_ReportDescription += ": non-existent physical address"; break; #endif #ifdef BUS_OBJERR case BUS_OBJERR: m_ReportDescription += ": object specific hardware error"; break; #endif default: break; } break; } case SIGFPE: { m_ReportDescription = "Floating-point error"; switch(m_pCrashInfo->code) { #ifdef FPE_INTDIV case FPE_INTDIV: m_ReportDescription += ": integer division by zero"; break; #endif #ifdef FPE_INTOVF case FPE_INTOVF: m_ReportDescription += ": integer overflow"; break; #endif #ifdef FPE_FLTDIV case FPE_FLTDIV: m_ReportDescription += ": floating point division by zero"; break; #endif #ifdef FPE_FLTOVF case FPE_FLTOVF: m_ReportDescription += ": floating point overflow"; break; #endif #ifdef FPE_FLTUND case FPE_FLTUND: m_ReportDescription += ": floating point underflow"; break; #endif #ifdef FPE_FLTRES case FPE_FLTRES: m_ReportDescription += ": floating point inexact result"; break; #endif #ifdef FPE_FLTINV case FPE_FLTINV: m_ReportDescription += ": invalid floating point operation"; break; #endif #ifdef FPE_FLTSUB case FPE_FLTSUB: m_ReportDescription += ": subscript out of range"; break; #endif default: break; } break; } case SIGSEGV: { m_ReportDescription = "Illegal storage access"; switch(m_pCrashInfo->code) { #ifdef SEGV_MAPERR case SEGV_MAPERR: { m_ReportDescription += ": address not mapped to object"; break; } #endif #ifdef SEGV_ACCERR case SEGV_ACCERR: { m_ReportDescription += ": invalid permissions for mapped object"; break; } #endif default: break; } break; } default: { m_ReportDescription = QString("Received signal %1").arg(m_pCrashInfo->signal); break; } } m_ReportDescription += "\n\n"; m_ReportDescriptionText = m_ReportDescription; #if defined(HAVE_FORK) && defined(HAVE_EXECLP) && defined(HAVE_DUP2) fs::path tracePath = m_ReportFolder / "gdbtrace.txt"; // Fork so we retain control after launching GDB. int childPID = fork(); if(childPID) { // Wait for GDB to exit. waitpid(childPID, NULL, 0); } else { // Redirect output to a file int fd = open(tracePath.string().c_str(), O_WRONLY|O_CREAT, 0666); dup2(fd, 1); close(fd); // Prepare pid argument for GDB. char pid_buf[30]; memset(&pid_buf, 0, sizeof(pid_buf)); sprintf(pid_buf, "%d", m_pCrashInfo->processId); // Try to execute gdb to get a very detailed stack trace. execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "set confirm off", "-ex", "set print frame-arguments all", "-ex", "set print static-members off", "-ex", "info threads", "-ex", "thread apply all bt full", m_pCrashInfo->execFullName, pid_buf, NULL); // GDB failed to start. exit(1); } #endif // defined(HAVE_EXECLP) && defined(HAVE_DUP2) bool bWroteDump = fs::exists(tracePath) && fs::file_size(tracePath) > 0; if(!bWroteDump) { m_DetailedError = "GDB is probably not installed on your machine. Please install it in order to obtain valuable crash reports in the future."; return false; } #ifdef HAVE_BACKTRACE boost::crc_32_type callstackCRC32; for(size_t i = 0; i < ARRAY_SIZE(m_pCrashInfo->backtrace); i++) { if(m_pCrashInfo->backtrace[i] == 0) { break; } callstackCRC32.process_bytes(&m_pCrashInfo->backtrace[i], sizeof(m_pCrashInfo->backtrace[i])); } u32 callstackCrc = callstackCRC32.checksum(); m_ReportUniqueID = QString("[%1]").arg(QString::number(callstackCrc, 16).toUpper()); #endif // HAVE_BACKTRACE QFile traceFile(tracePath.string().c_str()); traceFile.open(QIODevice::ReadOnly); if(!traceFile.isOpen()) { m_DetailedError = "Unable to read GDB output from the disk."; return false; } QString traceStr = traceFile.readAll(); traceFile.close(); QString callstackTop = "Unknown"; // The useful stack frames are found below "<signal handler called>" int posStart = traceStr.indexOf("<signal handler called>"); int posEnd = -1; if(posStart != -1) { posStart = traceStr.indexOf("#", posStart); if(posStart != -1) posEnd = traceStr.indexOf("\n", posStart); } // Capture the entry where the crash occured and format it if(posStart != -1 && posEnd != -1) { callstackTop = traceStr.mid(posStart, posEnd - posStart); // Remove "#N 0x???????? in " posEnd = callstackTop.indexOf(" in "); if(posEnd != -1) { posEnd += 4; callstackTop.remove(0, posEnd); } // Remove params posStart = callstackTop.indexOf("("); posEnd = callstackTop.indexOf(")", posStart); if(posStart != -1 && posEnd != -1) { posStart++; callstackTop.remove(posStart, posEnd - posStart); } // Trim filenames posStart = callstackTop.lastIndexOf(") at"); posEnd = callstackTop.lastIndexOf("/"); if(posStart != -1 && posEnd != -1) { posStart += 2; posEnd++; callstackTop.remove(posStart, posEnd - posStart); } } m_ReportDescription += "\nGDB stack trace:\n"; m_ReportDescription += "<source lang=\"gdb\">\n"; m_ReportDescription += traceStr; m_ReportDescription += "</source>\n"; m_ReportDescriptionText += "\nGDB stack trace:\n"; m_ReportDescriptionText += "\n"; m_ReportDescriptionText += traceStr; m_ReportTitle = QString("%1 %2").arg(m_ReportUniqueID, callstackTop.trimmed()); #endif // !defined(HAVE_WINAPI) return true; }
void replay() { TraceFileReader traceFile(_uri); Poco::Int64 epochFile(traceFile.getEpochStart()); auto epochCurrent = std::chrono::steady_clock::now(); const Poco::Int64 replayDuration = (traceFile.getEpochEnd() - epochFile); std::cout << "Replaying file [" << _uri << "] of " << replayDuration / 1000000. << " second length." << std::endl; for (;;) { const TraceFileRecord rec = traceFile.getNextRecord(); if (rec.getDir() == TraceFileRecord::Direction::Invalid) { // End of trace file. break; } const std::chrono::microseconds::rep deltaCurrent = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - epochCurrent).count(); const unsigned deltaFile = rec.getTimestampNs() - epochFile; const unsigned delay = (_ignoreTiming ? 0 : deltaFile - deltaCurrent); if (delay > 0) { if (delay > 1e6) { std::cout << "Sleeping for " << delay / 1000 << " ms.\n"; } std::this_thread::sleep_for(std::chrono::microseconds(delay)); } std::cout << rec.toString() << std::endl; if (rec.getDir() == TraceFileRecord::Direction::Event) { // Meta info about about an event. static const std::string NewSession("NewSession: "); static const std::string EndSession("EndSession: "); if (rec.getPayload().find(NewSession) == 0) { const std::string uriOrig = rec.getPayload().substr(NewSession.size()); std::string uri; Poco::URI::decode(uriOrig, uri); auto it = _sessions.find(uri); if (it != _sessions.end()) { // Add a new session. if (it->second.find(rec.getSessionId()) != it->second.end()) { std::cout << "ERROR: session [" << rec.getSessionId() << "] already exists on doc [" << uri << "]\n"; } else { std::shared_ptr<Connection> connection = Connection::create(_serverUri, uri, rec.getSessionId()); if (connection) { it->second.emplace(rec.getSessionId(), connection); } } } else { std::cout << "New Document: " << uri << "\n"; _childToDoc.emplace(rec.getPid(), uri); std::shared_ptr<Connection> connection = Connection::create(_serverUri, uri, rec.getSessionId()); if (connection) { _sessions[uri].emplace(rec.getSessionId(), connection); } } } else if (rec.getPayload().find(EndSession) == 0) { const std::string uriOrig = rec.getPayload().substr(EndSession.size()); std::string uri; Poco::URI::decode(uriOrig, uri); auto it = _sessions.find(uri); if (it != _sessions.end()) { std::cout << "EndSession [" << rec.getSessionId() << "]: " << uri << "\n"; it->second.erase(rec.getSessionId()); if (it->second.empty()) { std::cout << "End Doc [" << uri << "].\n"; _sessions.erase(it); _childToDoc.erase(rec.getPid()); } } else { std::cout << "ERROR: Doc [" << uri << "] does not exist.\n"; } } } else if (rec.getDir() == TraceFileRecord::Direction::Incoming) { auto docIt = _childToDoc.find(rec.getPid()); if (docIt != _childToDoc.end()) { const auto& uri = docIt->second; auto it = _sessions.find(uri); if (it != _sessions.end()) { const auto sessionIt = it->second.find(rec.getSessionId()); if (sessionIt != it->second.end()) { // Send the command. if (!sessionIt->second->send(rec.getPayload())) { it->second.erase(sessionIt); } } else { std::cout << "ERROR: Session [" << rec.getSessionId() << "] does not exist.\n"; } } else { std::cout << "ERROR: Doc [" << uri << "] does not exist.\n"; } } else { std::cout << "ERROR: Unknown PID [" << rec.getPid() << "] maps to no active document.\n"; } } else { std::cout << "ERROR: Unknown trace file direction [" << static_cast<char>(rec.getDir()) << "].\n"; } epochCurrent = std::chrono::steady_clock::now(); epochFile = rec.getTimestampNs(); } }