From 99a0819d935bbdfb34226e54ff50ed78b1fc6da0 Mon Sep 17 00:00:00 2001 From: Zdenek Prikryl Date: Wed, 1 Apr 2009 12:57:06 +0200 Subject: rewritten CDebugDump and CrashTypes --- lib/CommLayer/CommLayerServerDBus.cpp | 15 ++-- lib/CommLayer/CommLayerServerDBus.h | 6 +- lib/CommLayer/DBusCommon.h | 3 +- lib/CommLayer/DBusServerProxy.h | 12 ++-- lib/MiddleWare/CrashTypes.h | 80 +++++++++------------ lib/MiddleWare/MiddleWare.cpp | 99 +++++++++++++------------- lib/MiddleWare/MiddleWare.h | 10 +-- lib/MiddleWare/Reporter.h | 2 +- lib/MiddleWare/test.cpp | 19 ++--- lib/Plugins/CCpp.cpp | 2 +- lib/Plugins/Logger.cpp | 105 ++++++++++++++------------- lib/Plugins/Logger.h | 2 +- lib/Plugins/Mailx.cpp | 112 ++++++++++++++--------------- lib/Plugins/Mailx.h | 2 +- lib/Plugins/RunApp.h | 2 +- lib/Utils/DebugDump.cpp | 130 ++++++++++++++++++++++++---------- lib/Utils/DebugDump.h | 25 ++++--- lib/Utils/Makefile.am | 1 + 18 files changed, 336 insertions(+), 291 deletions(-) (limited to 'lib') diff --git a/lib/CommLayer/CommLayerServerDBus.cpp b/lib/CommLayer/CommLayerServerDBus.cpp index 81afd090..a5eb4372 100644 --- a/lib/CommLayer/CommLayerServerDBus.cpp +++ b/lib/CommLayer/CommLayerServerDBus.cpp @@ -17,7 +17,7 @@ CCommLayerServerDBus::CCommLayerServerDBus(CMiddleWare *pMW) { std::cerr << "CCommLayerDBus init.." << std::endl; m_pConn->request_name(CC_DBUS_NAME); - + } CCommLayerServerDBus::~CCommLayerServerDBus() @@ -58,17 +58,17 @@ dbus_vector_map_crash_infos_t CCommLayerServerDBus::GetCrashInfosMap(const std:: return retval; } -dbus_map_report_info_t CCommLayerServerDBus::CreateReport(const std::string &pUUID,const std::string &pDBusSender) +dbus_vector_crash_report_info_t CCommLayerServerDBus::CreateReport(const std::string &pUUID,const std::string &pDBusSender) { - dbus_map_report_info_t retval; + dbus_vector_crash_report_info_t retval; unsigned long unix_uid = m_pConn->sender_unix_uid(pDBusSender.c_str()); //std::cerr << pUUID << ":" << unix_uid << std::endl; crash_report_t crashReport; std::cerr << "Creating report" << std::endl; try { - m_pMW->CreateReport(pUUID,to_string(unix_uid), crashReport); - retval = crashReport.GetMap(); + m_pMW->CreateCrashReport(pUUID,to_string(unix_uid), crashReport); + retval = crash_report_to_vector_strings(crashReport); //send out the message about completed analyze CDBusServer_adaptor::AnalyzeComplete(retval); } @@ -80,9 +80,9 @@ dbus_map_report_info_t CCommLayerServerDBus::CreateReport(const std::string &pUU return retval; } -bool CCommLayerServerDBus::Report(dbus_map_report_info_t pReport) +bool CCommLayerServerDBus::Report(dbus_vector_crash_report_info_t pReport) { - crash_report_t crashReport; + crash_report_t crashReport = vector_strings_to_crash_report(pReport); //#define FIELD(X) crashReport.m_s##X = pReport[#X]; //crashReport.m_sUUID = pReport["UUID"]; //ALL_CRASH_REPORT_FIELDS; @@ -90,7 +90,6 @@ bool CCommLayerServerDBus::Report(dbus_map_report_info_t pReport) //for (dbus_map_report_info_t::iterator it = pReport.begin(); it!=pReport.end(); ++it) { // std::cerr << it->second << std::endl; //} - crashReport.SetFromMap(pReport); try { m_pMW->Report(crashReport); diff --git a/lib/CommLayer/CommLayerServerDBus.h b/lib/CommLayer/CommLayerServerDBus.h index 05ca0a47..9bd29c73 100644 --- a/lib/CommLayer/CommLayerServerDBus.h +++ b/lib/CommLayer/CommLayerServerDBus.h @@ -17,11 +17,11 @@ class CCommLayerServerDBus public: CCommLayerServerDBus(CMiddleWare *m_pMW); ~CCommLayerServerDBus(); - + virtual dbus_vector_crash_infos_t GetCrashInfos(const std::string &pUID); virtual dbus_vector_map_crash_infos_t GetCrashInfosMap(const std::string &pDBusSender); - virtual dbus_map_report_info_t CreateReport(const std::string &pUUID,const std::string &pDBusSender); - virtual bool Report(dbus_map_report_info_t pReport); + virtual dbus_vector_crash_report_info_t CreateReport(const std::string &pUUID,const std::string &pDBusSender); + virtual bool Report(dbus_vector_crash_report_info_t pReport); virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender); }; diff --git a/lib/CommLayer/DBusCommon.h b/lib/CommLayer/DBusCommon.h index 7582541c..acd508de 100644 --- a/lib/CommLayer/DBusCommon.h +++ b/lib/CommLayer/DBusCommon.h @@ -24,4 +24,5 @@ //typedef std::vector vector_crash_infos_t; typedef std::vector< std::vector > dbus_vector_crash_infos_t; typedef std::vector< std::map > dbus_vector_map_crash_infos_t; -typedef std::map dbus_map_report_info_t; +//typedef std::map dbus_map_report_info_t; +typedef std::vector dbus_vector_crash_report_info_t; diff --git a/lib/CommLayer/DBusServerProxy.h b/lib/CommLayer/DBusServerProxy.h index da6af721..f1c011a3 100644 --- a/lib/CommLayer/DBusServerProxy.h +++ b/lib/CommLayer/DBusServerProxy.h @@ -90,8 +90,8 @@ public: */ virtual dbus_vector_crash_infos_t GetCrashInfos(const std::string &pUID) = 0; virtual dbus_vector_map_crash_infos_t GetCrashInfosMap(const std::string &pDBusSender) = 0; - virtual dbus_map_report_info_t CreateReport(const std::string &pUUID,const std::string &pDBusSender) = 0; - virtual bool Report(dbus_map_report_info_t pReport) = 0; + virtual dbus_vector_crash_report_info_t CreateReport(const std::string &pUUID,const std::string &pDBusSender) = 0; + virtual bool Report(dbus_vector_crash_report_info_t pReport) = 0; virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender) = 0; public: @@ -106,14 +106,14 @@ public: emit_signal(sig); } /* Notify the clients that creating a report has finished */ - void AnalyzeComplete(dbus_map_report_info_t arg1) + void AnalyzeComplete(dbus_vector_crash_report_info_t arg1) { ::DBus::SignalMessage sig("AnalyzeComplete"); ::DBus::MessageIter wi = sig.writer(); wi << arg1; emit_signal(sig); } - + void Error(const std::string& arg1) { ::DBus::SignalMessage sig("Error"); @@ -143,7 +143,7 @@ private: DBus::MessageIter ri = call.reader(); std::string argin1; ri >> argin1; - dbus_map_report_info_t argout1 = CreateReport(argin1,call.sender()); + dbus_vector_crash_report_info_t argout1 = CreateReport(argin1,call.sender()); DBus::ReturnMessage reply(call); DBus::MessageIter wi = reply.writer(); wi << argout1; @@ -166,7 +166,7 @@ private: { DBus::MessageIter ri = call.reader(); - dbus_map_report_info_t argin1; ri >> argin1; + dbus_vector_crash_report_info_t argin1; ri >> argin1; bool argout1 = Report(argin1); DBus::ReturnMessage reply(call); DBus::MessageIter wi = reply.writer(); diff --git a/lib/MiddleWare/CrashTypes.h b/lib/MiddleWare/CrashTypes.h index f9fe625c..15338ca2 100644 --- a/lib/MiddleWare/CrashTypes.h +++ b/lib/MiddleWare/CrashTypes.h @@ -36,57 +36,45 @@ typedef struct SCrashInfo typedef std::vector vector_crash_infos_t; -typedef struct SCrashReport +#define TYPE_TXT "t" +#define TYPE_BIN "b" +#define TYPE_SYS "s" + +typedef struct CCrashFile { - std::string m_sMWID; - std::string m_sUUID; - std::string m_sArchitecture; - std::string m_sKernel; - std::string m_sRelease; - std::string m_sExecutable; - std::string m_sCmdLine; - std::string m_sPackage; - std::string m_sTextData1; - std::string m_sTextData2; - std::string m_sBinaryData1; - std::string m_sBinaryData2; - std::string m_sComment; + std::string m_sType; + std::string m_sContent; +} crash_file_t; - const map_crash_t GetMap() - { - map_crash_t mci; - mci["MWID"] = m_sMWID; - mci["UUID"] = m_sUUID; - mci["Architecture"] = m_sArchitecture; - mci["Kernel"] = m_sKernel; - mci["Release"] = m_sRelease; - mci["Executable"] = m_sExecutable; - mci["CmdLine"] = m_sCmdLine; - mci["Package"] = m_sPackage; - mci["TextData1"] = m_sTextData1; - mci["TextData2"] = m_sTextData2; - mci["BinaryData1"] = m_sBinaryData1; - mci["BinaryData2"] = m_sBinaryData2; - mci["Comment"] = m_sComment; +typedef std::vector vector_strings_t; +typedef std::map crash_report_t; - return mci; +inline vector_strings_t crash_report_to_vector_strings(const crash_report_t& pCrashReport) +{ + vector_strings_t vec; + crash_report_t::const_iterator it; + for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + { + vec.push_back(it->first); + vec.push_back(it->second.m_sType); + vec.push_back(it->second.m_sContent); } - void SetFromMap(const map_crash_t& pMcr) + return vec; +} + +inline crash_report_t vector_strings_to_crash_report(const vector_strings_t& pVectorStrings) +{ + unsigned int ii; + crash_report_t crashReport; + for (ii = 0; ii < pVectorStrings.size(); ii += 3) { - m_sMWID = pMcr.find("MWID")->second; - m_sUUID = pMcr.find("UUID")->second; - m_sArchitecture = pMcr.find("Architecture")->second; - m_sKernel = pMcr.find("Kernel")->second; - m_sRelease = pMcr.find("Release")->second; - m_sExecutable = pMcr.find("Executable")->second; - m_sCmdLine = pMcr.find("CmdLine")->second; - m_sPackage = pMcr.find("Package")->second; - m_sTextData1 = pMcr.find("TextData1")->second; - m_sTextData2 = pMcr.find("TextData2")->second; - m_sBinaryData1 = pMcr.find("BinaryData1")->second; - m_sBinaryData2 = pMcr.find("BinaryData2")->second; - m_sComment = pMcr.find("Comment")->second; + crash_file_t crashFile; + std::string fileName = pVectorStrings[ii]; + crashFile.m_sType = pVectorStrings[ii + 1]; + crashFile.m_sContent = pVectorStrings[ii + 2]; + crashReport[fileName] = crashFile; } -} crash_report_t; + return crashReport; +} #endif /* CRASHTYPES_H_ */ diff --git a/lib/MiddleWare/MiddleWare.cpp b/lib/MiddleWare/MiddleWare.cpp index 66d6f78d..00eca794 100644 --- a/lib/MiddleWare/MiddleWare.cpp +++ b/lib/MiddleWare/MiddleWare.cpp @@ -99,39 +99,34 @@ void CMiddleWare::LoadSettings(const std::string& pPath) } } -void CMiddleWare::DebugDump2Report(const std::string& pDebugDumpDir, crash_report_t& pCrashReport) +void CMiddleWare::DebugDumpToCrashReport(const std::string& pDebugDumpDir, crash_report_t& pCrashReport) { CDebugDump dd; dd.Open(pDebugDumpDir); - dd.LoadText(FILENAME_UUID, pCrashReport.m_sUUID); - dd.LoadText(FILENAME_ARCHITECTURE, pCrashReport.m_sArchitecture); - dd.LoadText(FILENAME_KERNEL, pCrashReport.m_sKernel); - dd.LoadText(FILENAME_PACKAGE, pCrashReport.m_sPackage); - dd.LoadText(FILENAME_EXECUTABLE, pCrashReport.m_sExecutable); + std::string fileName, content; + bool isTextFile; - if (dd.Exist(FILENAME_CMDLINE)) + if (!dd.Exist(FILENAME_UUID) || + !dd.Exist(FILENAME_ARCHITECTURE) || + !dd.Exist(FILENAME_KERNEL) || + !dd.Exist(FILENAME_PACKAGE)) { - dd.LoadText(FILENAME_CMDLINE, pCrashReport.m_sCmdLine); - } - if (dd.Exist(FILENAME_RELEASE)) - { - dd.LoadText(FILENAME_RELEASE, pCrashReport.m_sRelease); - } - if (dd.Exist(FILENAME_TEXTDATA1)) - { - dd.LoadText(FILENAME_TEXTDATA1, pCrashReport.m_sTextData1); - } - if (dd.Exist(FILENAME_TEXTDATA2)) - { - dd.LoadText(FILENAME_TEXTDATA2, pCrashReport.m_sTextData2); - } - if (dd.Exist(FILENAME_BINARYDATA1)) - { - pCrashReport.m_sBinaryData1 = pDebugDumpDir + "/" + FILENAME_BINARYDATA1; + dd.Close(); + throw std::string("CMiddleWare::DebugDumpToCrashReport(): One or more of important file(s)'re missing."); } - if (dd.Exist(FILENAME_BINARYDATA2)) + pCrashReport.clear(); + dd.InitGetNextFile(); + while (dd.GetNextFile(fileName, content, isTextFile)) { - pCrashReport.m_sBinaryData2 = pDebugDumpDir + "/" + FILENAME_BINARYDATA2; + crash_file_t crashFile; + crashFile.m_sType = TYPE_TXT; + if (!isTextFile) + { + crashFile.m_sType = TYPE_BIN; + content = pDebugDumpDir + "/" + fileName; + } + crashFile.m_sContent = content; + pCrashReport[fileName] = crashFile; } dd.Close(); } @@ -168,9 +163,9 @@ void CMiddleWare::CreateReport(const std::string& pAnalyzer, return analyzer->CreateReport(pDebugDumpDir); } -void CMiddleWare::CreateReport(const std::string& pUUID, - const std::string& pUID, - crash_report_t& pCrashReport) +void CMiddleWare::CreateCrashReport(const std::string& pUUID, + const std::string& pUID, + crash_report_t& pCrashReport) { CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase); database_row_t row; @@ -180,7 +175,7 @@ void CMiddleWare::CreateReport(const std::string& pUUID, if (pUUID == "" || row.m_sUUID != pUUID) { - throw std::string("CMiddleWare::CreateReport(): UUID '"+pUUID+"' is not in database."); + throw std::string("CMiddleWare::CreateCrashReport(): UUID '"+pUUID+"' is not in database."); } std::string analyzer; @@ -203,38 +198,46 @@ void CMiddleWare::CreateReport(const std::string& pUUID, dd.SaveText(FILENAME_UUID, UUID); dd.Close(); - DebugDump2Report(row.m_sDebugDumpDir, pCrashReport); + DebugDumpToCrashReport(row.m_sDebugDumpDir, pCrashReport); - pCrashReport.m_sMWID = analyzer + ";" + pUID + ";" + pUUID ; + crash_file_t file; + file.m_sType = TYPE_SYS; + file.m_sContent = analyzer; + pCrashReport["_MWAnalyzer"] = file; + file.m_sContent = pUID; + pCrashReport["_MWUID"] = file; + file.m_sContent = pUUID; + pCrashReport["_MWUUID"] = file; } void CMiddleWare::Report(const crash_report_t& pCrashReport) { - std::string::size_type pos1 = 0; - std::string::size_type pos2 = pCrashReport.m_sMWID.find(";", pos1); - std::string lanAppPlugin = pCrashReport.m_sMWID.substr(pos1, pos2); - pos1 = pos2 + 1; - pos2 = pCrashReport.m_sMWID.find(";", pos1); - std::string UID = pCrashReport.m_sMWID.substr(pos1, pos2 - pos1); - pos1 = pos2 + 1; - std::string UUID = pCrashReport.m_sMWID.substr(pos1);; - - CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase); - database->Connect(); - database->SetReported(UUID, UID); - database->DisConnect(); + if (pCrashReport.find("_MWAnalyzer") == pCrashReport.end() || + pCrashReport.find("_MWUID") == pCrashReport.end() || + pCrashReport.find("_MWUUID") == pCrashReport.end()) + { + throw std::string("CMiddleWare::Report(): Important data are missing."); + } + std::string analyzer = pCrashReport.find("_MWAnalyzer")->second.m_sContent; + std::string UID = pCrashReport.find("_MWUID")->second.m_sContent; + std::string UUID = pCrashReport.find("_MWUUID")->second.m_sContent;; - if (m_mapPlugin2Reporters.find(lanAppPlugin) != m_mapPlugin2Reporters.end()) + if (m_mapPlugin2Reporters.find(analyzer) != m_mapPlugin2Reporters.end()) { set_reporters_t::iterator it_r; - for (it_r = m_mapPlugin2Reporters[lanAppPlugin].begin(); - it_r != m_mapPlugin2Reporters[lanAppPlugin].end(); + for (it_r = m_mapPlugin2Reporters[analyzer].begin(); + it_r != m_mapPlugin2Reporters[analyzer].end(); it_r++) { CReporter* reporter = m_pPluginManager->GetReporter(*it_r); reporter->Report(pCrashReport); } } + + CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase); + database->Connect(); + database->SetReported(UUID, UID); + database->DisConnect(); } void CMiddleWare::DeleteCrashInfo(const std::string& pUUID, diff --git a/lib/MiddleWare/MiddleWare.h b/lib/MiddleWare/MiddleWare.h index def29ce6..82b734b7 100644 --- a/lib/MiddleWare/MiddleWare.h +++ b/lib/MiddleWare/MiddleWare.h @@ -57,8 +57,8 @@ class CMiddleWare void LoadSettings(const std::string& pPath); - void DebugDump2Report(const std::string& pDebugDumpDir, - crash_report_t& pCrashReport); + void DebugDumpToCrashReport(const std::string& pDebugDumpDir, + crash_report_t& pCrashReport); bool IsDebugDumpSaved(const std::string& pDebugDumpDir); int SavePackageDescriptionToDebugDump(const std::string& pDebugDumpDir); @@ -78,9 +78,9 @@ class CMiddleWare void RegisterPlugin(const std::string& pName); void UnRegisterPlugin(const std::string& pName); - void CreateReport(const std::string& pUUID, - const std::string& pUID, - crash_report_t& pCrashReport); + void CreateCrashReport(const std::string& pUUID, + const std::string& pUID, + crash_report_t& pCrashReport); void Report(const crash_report_t& pCrashReport); diff --git a/lib/MiddleWare/Reporter.h b/lib/MiddleWare/Reporter.h index 80fe6687..b3d8b8ca 100644 --- a/lib/MiddleWare/Reporter.h +++ b/lib/MiddleWare/Reporter.h @@ -31,7 +31,7 @@ class CReporter : public CPlugin public: virtual ~CReporter() {} - virtual void Report(const crash_report_t& pReport) = 0; + virtual void Report(const crash_report_t& pCrashReport) = 0; }; #endif /* REPORTER_H_ */ diff --git a/lib/MiddleWare/test.cpp b/lib/MiddleWare/test.cpp index 633a6544..8f5afc9a 100644 --- a/lib/MiddleWare/test.cpp +++ b/lib/MiddleWare/test.cpp @@ -25,29 +25,25 @@ #include #include #include +#include int main(int argc, char** argv) { - + if (argc < 2) + { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + } try { CMiddleWare middleWare(PLUGINS_CONF_DIR, PLUGINS_LIB_DIR, std::string(CONF_DIR) + "/abrt.conf"); /* Create DebugDump */ - CDebugDump dd; - char pid[100]; - sprintf(pid, "%d", getpid()); - dd.Create(std::string(DEBUG_DUMPS_DIR)+"/"+pid); - dd.SaveProc(pid); - dd.SaveText(FILENAME_ANALYZER, "CCpp"); - dd.SaveBinary(FILENAME_BINARYDATA1, "ass0-9as", sizeof("ass0-9as")); - /* Try to save it into DB */ crash_info_t crashInfo; - if (middleWare.SaveDebugDump(std::string(DEBUG_DUMPS_DIR)+"/"+pid, crashInfo)) + if (middleWare.SaveDebugDump(argv[1], crashInfo)) { std::cout << "Application Crashed! " << "(" << crashInfo.m_sTime << " [" << crashInfo.m_sCount << "]) " << @@ -58,11 +54,10 @@ int main(int argc, char** argv) * If we do not want user interaction, just send data immediately */ crash_report_t crashReport; - middleWare.CreateReport(crashInfo.m_sUUID, crashInfo.m_sUID, crashReport); + middleWare.CreateCrashReport(crashInfo.m_sUUID, crashInfo.m_sUID, crashReport); /* Report crash */ middleWare.Report(crashReport); } - dd.Close(); } catch (std::string sError) { diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 2eb1cead..e0f37144 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -35,7 +35,7 @@ #include #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" -#define CORE_PATTERN "|"CCPP_HOOK_PATH" %p %s" +#define CORE_PATTERN "|"CCPP_HOOK_PATH" %p %s %u" CAnalyzerCCpp::CAnalyzerCCpp() : m_bMemoryMap(false) diff --git a/lib/Plugins/Logger.cpp b/lib/Plugins/Logger.cpp index e7579372..3b48d5e8 100644 --- a/lib/Plugins/Logger.cpp +++ b/lib/Plugins/Logger.cpp @@ -22,6 +22,8 @@ #include "Logger.h" #include #include "Settings.h" +#include +#include "DebugDump.h" CLogger::CLogger() : m_sLogPath("/var/log/abrt-logger"), @@ -43,9 +45,47 @@ void CLogger::LoadSettings(const std::string& pPath) } } -void CLogger::Report(const crash_report_t& pReport) +void CLogger::Report(const crash_report_t& pCrashReport) { + std::stringstream binaryFiles, commonFiles, additionalFiles, UUIDFile; std::ofstream fOut; + + crash_report_t::const_iterator it; + for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + { + if (it->second.m_sType == TYPE_TXT) + { + if (it->first != FILENAME_UUID && + it->first != FILENAME_ARCHITECTURE && + it->first != FILENAME_KERNEL && + it->first != FILENAME_PACKAGE) + { + additionalFiles << it->first << std::endl; + additionalFiles << "-----" << std::endl; + additionalFiles << it->second.m_sContent << std::endl << std::endl; + } + else if (it->first == FILENAME_UUID) + { + UUIDFile << it->first << std::endl; + UUIDFile << "-----" << std::endl; + UUIDFile << it->second.m_sContent << std::endl << std::endl; + } + else + { + commonFiles << it->first << std::endl; + commonFiles << "-----" << std::endl; + commonFiles << it->second.m_sContent << std::endl << std::endl; + } + } + if (it->second.m_sType == TYPE_BIN) + { + binaryFiles << it->first << std::endl; + binaryFiles << "-----" << std::endl; + binaryFiles << it->second.m_sContent << std::endl << std::endl; + } + } + + if (m_bAppendLogs) { fOut.open(m_sLogPath.c_str(), std::ios::app); @@ -56,60 +96,19 @@ void CLogger::Report(const crash_report_t& pReport) } if (fOut.is_open()) { + fOut << "Duplicity check" << std::endl; - fOut << "==================" << std::endl << std::endl; - fOut << "UUID" << std::endl; - fOut << "------------" << std::endl; - fOut << pReport.m_sUUID << std::endl << std::endl; + fOut << "======" << std::endl << std::endl; + fOut << UUIDFile.str() << std::endl; fOut << "Common information" << std::endl; - fOut << "==================" << std::endl << std::endl; - fOut << "Architecture" << std::endl; - fOut << "------------" << std::endl; - fOut << pReport.m_sArchitecture << std::endl << std::endl; - fOut << "Kernel version" << std::endl; - fOut << "--------------" << std::endl; - fOut << pReport.m_sKernel << std::endl << std::endl; - fOut << "Package" << std::endl; - fOut << "-------" << std::endl; - fOut << pReport.m_sPackage << std::endl << std::endl; - fOut << "Executable" << std::endl; - fOut << "----------" << std::endl; - fOut << pReport.m_sExecutable << std::endl << std::endl; - fOut << "CmdLine" << std::endl; - fOut << "----------" << std::endl; - fOut << pReport.m_sCmdLine << std::endl << std::endl; - fOut << "Created report" << std::endl; - fOut << "==============" << std::endl; - fOut << "Text reports" << std::endl; - fOut << "==============" << std::endl; - if (pReport.m_sTextData1 != "") - { - fOut << "Text Data 1" << std::endl; - fOut << "-----------" << std::endl; - fOut << pReport.m_sTextData1 << std::endl << std::endl; - } - if (pReport.m_sTextData2 != "") - { - fOut << "Text Data 2" << std::endl; - fOut << "-----------" << std::endl; - fOut << pReport.m_sTextData2 << std::endl << std::endl; - } - if (pReport.m_sComment != "") - { - fOut << "User Comments" << std::endl; - fOut << "-----------" << std::endl; - fOut << pReport.m_sComment << std::endl << std::endl; - } - fOut << "Binary reports" << std::endl; - fOut << "==============" << std::endl; - if (pReport.m_sBinaryData1 != "") - { - fOut << "1. " << pReport.m_sBinaryData1 << std::endl; - } - if (pReport.m_sBinaryData2 != "") - { - fOut << "2. " << pReport.m_sBinaryData2 << std::endl; - } + fOut << "======" << std::endl << std::endl; + fOut << commonFiles.str() << std::endl; + fOut << "Additional information" << std::endl; + fOut << "======" << std::endl << std::endl; + fOut << additionalFiles.str() << std::endl; + fOut << "Binary files" << std::endl; + fOut << "======" << std::endl; + fOut << binaryFiles.str() << std::endl; fOut << std::endl; fOut.close(); } diff --git a/lib/Plugins/Logger.h b/lib/Plugins/Logger.h index f6dcffd8..f465ee05 100644 --- a/lib/Plugins/Logger.h +++ b/lib/Plugins/Logger.h @@ -36,7 +36,7 @@ class CLogger : public CReporter virtual ~CLogger() {} void LoadSettings(const std::string& pPath); - void Report(const crash_report_t& pReport); + void Report(const crash_report_t& pCrashReport); }; diff --git a/lib/Plugins/Mailx.cpp b/lib/Plugins/Mailx.cpp index 1f83cb55..8c0c4a6b 100644 --- a/lib/Plugins/Mailx.cpp +++ b/lib/Plugins/Mailx.cpp @@ -58,71 +58,69 @@ void CMailx::SendEmail(const std::string& pText) } -void CMailx::Report(const crash_report_t& pReport) +void CMailx::Report(const crash_report_t& pCrashReport) { - std::stringstream ss; - - ss << "Duplicity check" << std::endl; - ss << "==================" << std::endl << std::endl; - ss << "UUID" << std::endl; - ss << "------------" << std::endl; - ss << pReport.m_sUUID << std::endl << std::endl; - ss << "Common information" << std::endl; - ss << "==================" << std::endl << std::endl; - ss << "Architecture" << std::endl; - ss << "------------" << std::endl; - ss << pReport.m_sArchitecture << std::endl << std::endl; - ss << "Kernel version" << std::endl; - ss << "--------------" << std::endl; - ss << pReport.m_sKernel << std::endl << std::endl; - ss << "Package" << std::endl; - ss << "-------" << std::endl; - ss << pReport.m_sPackage << std::endl << std::endl; - ss << "Executable" << std::endl; - ss << "----------" << std::endl; - ss << pReport.m_sExecutable << std::endl << std::endl; - ss << "CmdLine" << std::endl; - ss << "----------" << std::endl; - ss << pReport.m_sCmdLine << std::endl << std::endl; - ss << "Created report" << std::endl; - ss << "==============" << std::endl; - ss << "Text reports" << std::endl; - ss << "==============" << std::endl; - if (pReport.m_sTextData1 != "") - { - ss << "Text Data 1" << std::endl; - ss << "-----------" << std::endl; - ss << pReport.m_sTextData1 << std::endl << std::endl; - } - if (pReport.m_sTextData2 != "") - { - ss << "Text Data 2" << std::endl; - ss << "-----------" << std::endl; - ss << pReport.m_sTextData2 << std::endl << std::endl; - } - if (pReport.m_sComment != "") - { - ss << "User Comments" << std::endl; - ss << "-----------" << std::endl; - ss << pReport.m_sComment << std::endl << std::endl; - } - ss << "Binary reports" << std::endl; - ss << "==============" << std::endl; - ss << "See the attachment[s]" << std::endl; + std::stringstream emailBody; + std::stringstream binaryFiles, commonFiles, additionalFiles, UUIDFile; - if (m_bSendBinaryData) + crash_report_t::const_iterator it; + for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) { - if (pReport.m_sBinaryData1 != "") + if (it->second.m_sType == TYPE_TXT) { - m_sAttachments = " -a " + pReport.m_sBinaryData1; + if (it->first != FILENAME_UUID && + it->first != FILENAME_ARCHITECTURE && + it->first != FILENAME_KERNEL && + it->first != FILENAME_PACKAGE) + { + additionalFiles << it->first << std::endl; + additionalFiles << "-----" << std::endl; + additionalFiles << it->second.m_sContent << std::endl; + } + else if (it->first == FILENAME_UUID) + { + UUIDFile << it->first << std::endl; + UUIDFile << "-----" << std::endl; + UUIDFile << it->second.m_sContent << std::endl; + } + else + { + commonFiles << it->first << std::endl; + commonFiles << "-----" << std::endl; + commonFiles << it->second.m_sContent << std::endl; + } } - if (pReport.m_sBinaryData2 != "") + if (it->second.m_sType == TYPE_BIN) { - m_sAttachments = " -a " + pReport.m_sBinaryData2; + binaryFiles << " -a " << it->second.m_sContent; } } - SendEmail(ss.str()); + + + emailBody << "Duplicity check" << std::endl; + emailBody << "=====" << std::endl << std::endl; + emailBody << UUIDFile.str() << std::endl; + emailBody << "Common information" << std::endl; + emailBody << "=====" << std::endl << std::endl; + emailBody << commonFiles.str() << std::endl; + emailBody << "Additional information" << std::endl; + emailBody << "=====" << std::endl << std::endl; + emailBody << additionalFiles.str() << std::endl; + emailBody << "Binary file[s]" << std::endl; + emailBody << "=====" << std::endl; + + if (m_bSendBinaryData) + { + emailBody << "See the attachment[s]" << std::endl; + m_sAttachments = binaryFiles.str(); + } + else + { + emailBody << "Do not send them." << std::endl; + } + + SendEmail(emailBody.str()); } void CMailx::LoadSettings(const std::string& pPath) @@ -144,6 +142,6 @@ void CMailx::LoadSettings(const std::string& pPath) } if (settings.find("SendBinaryData")!= settings.end()) { - m_bSendBinaryData = settings["SendBinaryData"] == "yes"; + m_bSendBinaryData = settings["SendBinaryData"] == "no"; } } diff --git a/lib/Plugins/Mailx.h b/lib/Plugins/Mailx.h index 15072632..0303bb65 100644 --- a/lib/Plugins/Mailx.h +++ b/lib/Plugins/Mailx.h @@ -43,7 +43,7 @@ class CMailx : public CReporter virtual ~CMailx() {} void LoadSettings(const std::string& pPath); - void Report(const crash_report_t& pReport); + void Report(const crash_report_t& pCrashReport); }; diff --git a/lib/Plugins/RunApp.h b/lib/Plugins/RunApp.h index d075cbb8..1ffd00a8 100644 --- a/lib/Plugins/RunApp.h +++ b/lib/Plugins/RunApp.h @@ -35,7 +35,7 @@ class CActionRunApp : public CAction public: virtual ~CActionRunApp() {} virtual void Run(const std::string& pDebugDumpDir, - const std::string& pParams); + const std::string& pArgs); }; PLUGIN_INFO(ACTION, diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp index 883d6b91..198b668d 100644 --- a/lib/Utils/DebugDump.cpp +++ b/lib/Utils/DebugDump.cpp @@ -32,11 +32,14 @@ #include #include #include +#include +#include CDebugDump::CDebugDump() : m_sDebugDumpDir(""), m_bOpened(false), - m_bUnlock(true) + m_bUnlock(true), + m_pGetNextFileDir(NULL) {} void CDebugDump::Open(const std::string& pDir) @@ -157,7 +160,7 @@ void CDebugDump::Create(const std::string& pDir) throw "CDebugDump::Create(): Cannot create dir: " + pDir; } - SaveEnvironment(); + SaveKernelArchitectureRelease(); SaveTime(); } @@ -195,6 +198,39 @@ void CDebugDump::DeleteFileDir(const std::string& pDir) } } +bool CDebugDump::IsTextFile(const std::string& pName) +{ + bool isText = false; + magic_t m = magic_open(MAGIC_MIME); + + if (m == NULL) + { + throw std::string("CDebugDump::IsTextFile(): Cannot open magic cookie: ") + magic_error(m); + } + + int r = magic_load(m,NULL); + + if (r == -1) + { + throw std::string("CDebugDump::IsTextFile(): Cannot load magic db: ") + magic_error(m); + } + + char* ch = (char *) magic_file(m, pName.c_str()); + + if (ch == NULL) + { + throw std::string("CDebugDump::IsTextFile(): Cannot determine file type: ") + magic_error(m); + } + + if (!strncmp(ch, "text", 4)) + { + isText = true; + } + + magic_close(m); + return isText; +} + void CDebugDump::Delete() { if (!ExistFileDir(m_sDebugDumpDir)) @@ -210,7 +246,7 @@ void CDebugDump::Close() m_bOpened = false; } -void CDebugDump::SaveEnvironment() +void CDebugDump::SaveKernelArchitectureRelease() { struct utsname buf; if (uname(&buf) == 0) @@ -242,16 +278,18 @@ void CDebugDump::LoadTextFile(const std::string& pPath, std::string& pData) fIn.open(pPath.c_str()); if (fIn.is_open()) { - std::string line; - while (!fIn.eof()) + // TODO: rewrite this + int ch; + while ((ch = fIn.get())!= EOF) { - getline (fIn,line); - // TODO: remove this hack - if (pData != "") - { - pData += "\n"; - } - pData += line; + if (ch == 0) + { + pData += " "; + } + else if (isspace(ch) || (isascii(ch) && !iscntrl(ch))) + { + pData += ch; + } } fIn.close(); } @@ -291,6 +329,10 @@ void CDebugDump::SaveTextFile(const std::string& pPath, const std::string& pData if (fOut.is_open()) { fOut << pData; + if (!fOut.good()) + { + throw "CDebugDump: SaveTextFile(): Cannot save file " + pPath; + } fOut.close(); } else @@ -306,6 +348,10 @@ void CDebugDump::SaveBinaryFile(const std::string& pPath, const char* pData, con if (fOut.is_open()) { fOut.write(pData, pSize); + if (!fOut.good()) + { + throw "CDebugDump: SaveBinaryFile(): Cannot save file " + pPath; + } fOut.close(); } else @@ -336,36 +382,46 @@ void CDebugDump::SaveBinary(const std::string& pName, const char* pData, const u SaveBinaryFile(fullPath, pData, pSize); } - -void CDebugDump::SaveProc(const std::string& pPID) +void CDebugDump::InitGetNextFile() { - std::string path = "/proc/"+pPID+"/exe"; - std::string data; - char executable[PATH_MAX]; - int len; - - if ((len = readlink(path.c_str(), executable, PATH_MAX)) != -1) + if (m_pGetNextFileDir != NULL) { - executable[len] = '\0'; - SaveText(FILENAME_EXECUTABLE, executable); + closedir(m_pGetNextFileDir); + m_pGetNextFileDir= NULL; } + m_pGetNextFileDir = opendir(m_sDebugDumpDir.c_str()); + if (m_pGetNextFileDir == NULL) + { + throw "CDebugDump::InitGetNextFile(): Cannot open dir " + m_sDebugDumpDir; + } +} +bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool& pIsTextFile) +{ + static struct dirent *dent = NULL; - path = "/proc/"+pPID+"/status"; - std::string uid = ""; - int ii = 0; - - LoadTextFile(path, data); - data = data.substr(data.find("Uid:")+5); - - while (!isspace(data[ii])) + if (m_pGetNextFileDir == NULL) { - uid += data[ii]; - ii++; + false; } - SaveText(FILENAME_UID, uid); - - path = "/proc/"+pPID+"/cmdline"; - LoadTextFile(path, data); - SaveText(FILENAME_CMDLINE, data); + while ((dent = readdir(m_pGetNextFileDir)) != NULL) + { + if (dent->d_type == DT_REG) + { + pFileName = dent->d_name; + if (IsTextFile(m_sDebugDumpDir + "/" + pFileName)) + { + LoadText(pFileName, pContent); + pIsTextFile = true; + } + else + { + pContent = ""; + pIsTextFile = false; + } + return true; + } + } + return false; } + diff --git a/lib/Utils/DebugDump.h b/lib/Utils/DebugDump.h index 5805a82e..94323e4c 100644 --- a/lib/Utils/DebugDump.h +++ b/lib/Utils/DebugDump.h @@ -24,22 +24,23 @@ #define DEBUGDUMP_H_ #include +#include #define FILENAME_UUID "uuid" #define FILENAME_ARCHITECTURE "architecture" #define FILENAME_KERNEL "kernel" -#define FILENAME_RELEASE "release" -#define FILENAME_EXECUTABLE "executable" -#define FILENAME_CMDLINE "cmdline" #define FILENAME_TIME "time" #define FILENAME_UID "uid" #define FILENAME_PACKAGE "package" #define FILENAME_DESCRIPTION "description" #define FILENAME_ANALYZER "analyzer" -#define FILENAME_TEXTDATA1 "text_data1" -#define FILENAME_TEXTDATA2 "text_data2" -#define FILENAME_BINARYDATA1 "binary_data1" -#define FILENAME_BINARYDATA2 "binary_data2" +#define FILENAME_RELEASE "release" +#define FILENAME_EXECUTABLE "executable" +#define FILENAME_CMDLINE "cmdline" +#define FILENAME_TEXTDATA1 "text_data_1" +#define FILENAME_TEXTDATA2 "text_data_2" +#define FILENAME_BINARYDATA1 "binary_data_1" +#define FILENAME_BINARYDATA2 "binary_data_1" class CDebugDump { @@ -47,8 +48,9 @@ class CDebugDump std::string m_sDebugDumpDir; bool m_bOpened; bool m_bUnlock; + DIR* m_pGetNextFileDir; - void SaveEnvironment(); + void SaveKernelArchitectureRelease(); void SaveTime(); void LoadTextFile(const std::string& pName, std::string& pData); @@ -64,6 +66,8 @@ class CDebugDump void DeleteFileDir(const std::string& pDir); + bool IsTextFile(const std::string& pName); + public: CDebugDump(); @@ -72,8 +76,6 @@ class CDebugDump void Delete(); void Close(); - void SaveProc(const std::string& pPID); - bool Exist(const std::string& pFileName); void LoadText(const std::string& pName, std::string& pData); @@ -81,6 +83,9 @@ class CDebugDump void SaveText(const std::string& pName, const std::string& pData); void SaveBinary(const std::string& pName, const char* pData, const unsigned int pSize); + + void InitGetNextFile(); + bool GetNextFile(std::string& pFileName, std::string& pContent, bool& pIsTextFile); }; #endif /*DEBUGDUMP_H_*/ diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index c9bef6d4..5e255096 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -1,6 +1,7 @@ lib_LTLIBRARIES = libUtils.la libUtils_la_SOURCES = DebugDump.cpp DebugDump.h Settings.h libUtils_la_LDFLAGS = -version-info 0:1:0 +libUtils_la_LIBADD = -lmagic install-data-local: $(mkdir_p) '$(DESTDIR)/$(DEBUG_DUMPS_DIR)' \ No newline at end of file -- cgit