Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
	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;
}
Ejemplo n.º 4
0
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);
        }
    }

}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
    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();
        }
    }