diff options
author | Jiri Moskovcak <jmoskovc@redhat.com> | 2009-02-12 12:34:25 +0100 |
---|---|---|
committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2009-02-12 12:34:25 +0100 |
commit | 53821dddf0b6ee66dc5f0684b17c541c157656ec (patch) | |
tree | 00dcb130b6fd32ef137cd7b139bbebfeb0c060b4 | |
parent | 356da89a4e2e6e50ceade12f286d104fe1c17eae (diff) | |
parent | c93222d1407ede085833d3a91bfeda5f0f910eb4 (diff) | |
download | abrt-53821dddf0b6ee66dc5f0684b17c541c157656ec.tar.gz abrt-53821dddf0b6ee66dc5f0684b17c541c157656ec.tar.xz abrt-53821dddf0b6ee66dc5f0684b17c541c157656ec.zip |
Merge branch 'master' of git://git.fedorahosted.org/git/crash-catcher
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | lib/MiddleWare/Application.h | 3 | ||||
-rw-r--r-- | lib/MiddleWare/CrashCatcher.conf | 7 | ||||
-rw-r--r-- | lib/MiddleWare/Database.h | 5 | ||||
-rw-r--r-- | lib/MiddleWare/DynamicLibrary.cpp | 1 | ||||
-rw-r--r-- | lib/MiddleWare/DynamicLibrary.h | 1 | ||||
-rw-r--r-- | lib/MiddleWare/Language.h | 3 | ||||
-rw-r--r-- | lib/MiddleWare/MiddleWare.cpp | 155 | ||||
-rw-r--r-- | lib/MiddleWare/MiddleWare.h | 60 | ||||
-rw-r--r-- | lib/MiddleWare/Reporter.h | 15 | ||||
-rw-r--r-- | lib/MiddleWare/Settings.cpp | 13 | ||||
-rw-r--r-- | lib/MiddleWare/Settings.h | 3 | ||||
-rw-r--r-- | lib/MiddleWare/test.cpp | 28 | ||||
-rw-r--r-- | lib/Plugins/CCpp.cpp | 34 | ||||
-rw-r--r-- | lib/Plugins/CCpp.h | 5 | ||||
-rw-r--r-- | lib/Plugins/Mailx.cpp | 68 | ||||
-rw-r--r-- | lib/Plugins/Mailx.h | 3 | ||||
-rw-r--r-- | lib/Plugins/SQLite3.cpp | 23 | ||||
-rw-r--r-- | lib/Plugins/SQLite3.h | 3 | ||||
-rw-r--r-- | lib/Utils/DebugDump.cpp | 30 | ||||
-rw-r--r-- | lib/Utils/DebugDump.h | 9 | ||||
-rw-r--r-- | lib/Utils/Makefile.am | 4 | ||||
-rw-r--r-- | lib/Utils/Packages.cpp | 73 | ||||
-rw-r--r-- | lib/Utils/Packages.h | 9 | ||||
-rw-r--r-- | src/Hooks/CCpp.cpp | 17 |
25 files changed, 395 insertions, 178 deletions
diff --git a/configure.ac b/configure.ac index b507e97a..baefc132 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,7 @@ PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1]) PKG_CHECK_MODULES([SQLITE3], [sqlite3]) PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4]) PKG_CHECK_MODULES([PACKAGEKIT_GLIB], [packagekit-glib]) +PKG_CHECK_MODULES([RPM], [rpm]) AC_CHECK_HEADER([sys/inotify.h], [], [AC_MSG_ERROR([sys/inotify.h is needed to build CrashCatcher])]) diff --git a/lib/MiddleWare/Application.h b/lib/MiddleWare/Application.h index 598fc184..8b1d7eca 100644 --- a/lib/MiddleWare/Application.h +++ b/lib/MiddleWare/Application.h @@ -30,7 +30,8 @@ class CApplication : public CPlugin public: virtual ~CApplication() {} virtual std::string GetLocalUUID(const std::string& pDebugDumpPath) = 0; - virtual std::string GetReport(const std::string& pDebugDumpPath) = 0; + virtual std::string GetGlobalUUID(const std::string& pDebugDumpPath) = 0; + virtual void CreateReport(const std::string& pDebugDumpPath) = 0; }; #endif /*APPLICATION_H_*/ diff --git a/lib/MiddleWare/CrashCatcher.conf b/lib/MiddleWare/CrashCatcher.conf index c4c2c17a..e865ebec 100644 --- a/lib/MiddleWare/CrashCatcher.conf +++ b/lib/MiddleWare/CrashCatcher.conf @@ -1,4 +1,9 @@ # test conf file. it will be generated in the future +# blacklisted packages BlackList = bash, bind, apache2 -EnabledPlugins = SQLite3, CCpp +# enabled plugins +EnabledPlugins = SQLite3, CCpp, Mailx +# selected DB plugin Database = SQLite3 +# reporters association +CCpp = Mailx
\ No newline at end of file diff --git a/lib/MiddleWare/Database.h b/lib/MiddleWare/Database.h index 15b20a9a..84099af4 100644 --- a/lib/MiddleWare/Database.h +++ b/lib/MiddleWare/Database.h @@ -40,6 +40,7 @@ #define DATABASE_COLUMN_DEBUG_DUMP_PATH "DebugDumpPath" #define DATABASE_COLUMN_COUNT "Count" #define DATABASE_COLUMN_REPORTED "Reported" +#define DATABASE_COLUMN_TIME "Time" typedef struct SDatabaseRow { @@ -48,6 +49,7 @@ typedef struct SDatabaseRow std::string m_sDebugDumpPath; std::string m_sCount; std::string m_sReported; + std::string m_sTime; } database_row_t; // <column_name, <array of values in all selected rows> > @@ -62,7 +64,8 @@ class CDatabase : public CPlugin virtual void DisConnect() = 0; virtual void Insert(const std::string& pUUID, const std::string& pUID, - const std::string& pDebugDumpPath) = 0; + const std::string& pDebugDumpPath, + const std::string& pTime) = 0; virtual void Delete(const std::string& pUUID, const std::string& pUID) = 0; diff --git a/lib/MiddleWare/DynamicLibrary.cpp b/lib/MiddleWare/DynamicLibrary.cpp index 35a69c7e..3fcc548c 100644 --- a/lib/MiddleWare/DynamicLibrary.cpp +++ b/lib/MiddleWare/DynamicLibrary.cpp @@ -21,6 +21,7 @@ #include "DynamicLibrary.h" #include <iostream> +#include <dlfcn.h> CDynamicLibrary::CDynamicLibrary(const std::string& pPath) : m_pHandle(NULL) diff --git a/lib/MiddleWare/DynamicLibrary.h b/lib/MiddleWare/DynamicLibrary.h index 0182fb22..4cf36f6a 100644 --- a/lib/MiddleWare/DynamicLibrary.h +++ b/lib/MiddleWare/DynamicLibrary.h @@ -24,7 +24,6 @@ #define DYNAMICLIBRARYH_ #include <string> -#include <dlfcn.h> class CDynamicLibrary { diff --git a/lib/MiddleWare/Language.h b/lib/MiddleWare/Language.h index b83434b5..60e82757 100644 --- a/lib/MiddleWare/Language.h +++ b/lib/MiddleWare/Language.h @@ -30,7 +30,8 @@ class CLanguage : public CPlugin public: virtual ~CLanguage() {} virtual std::string GetLocalUUID(const std::string& pDebugDumpPath) = 0; - virtual std::string GetReport(const std::string& pDebugDumpPath) = 0; + virtual std::string GetGlobalUUID(const std::string& pDebugDumpPath) = 0; + virtual void CreateReport(const std::string& pDebugDumpPath) = 0; }; #endif /*LANGUAGE_H_*/ diff --git a/lib/MiddleWare/MiddleWare.cpp b/lib/MiddleWare/MiddleWare.cpp index d52fbdae..5a5e39d4 100644 --- a/lib/MiddleWare/MiddleWare.cpp +++ b/lib/MiddleWare/MiddleWare.cpp @@ -49,36 +49,17 @@ CMiddleWare::~CMiddleWare() delete m_pPluginManager; } - void CMiddleWare::LoadSettings(const std::string& pPath) { map_settings_t settings; load_settings(pPath, settings); if (settings.find("BlackList") != settings.end()) { - std::string blackList = settings["BlackList"]; - std::string::size_type ii_old = 0, ii_new = 0; - ii_new = blackList.find(","); - while (ii_new != std::string::npos) - { - m_setBlackList.insert(blackList.substr(ii_old, ii_new - ii_old)); - ii_old = ii_new + 1; - ii_new = blackList.find(",",ii_old); - } - m_setBlackList.insert(blackList.substr(ii_old)); + parse_settings(settings["BlackList"], m_setBlackList); } if (settings.find("EnabledPlugins") != settings.end()) { - std::string enabledPlugins = settings["EnabledPlugins"]; - std::string::size_type ii_old = 0, ii_new = 0; - ii_new = enabledPlugins.find(","); - while (ii_new != std::string::npos) - { - m_setEnabledPlugins.insert(enabledPlugins.substr(ii_old, ii_new - ii_old)); - ii_old = ii_new + 1; - ii_new = enabledPlugins.find(",",ii_old); - } - m_setEnabledPlugins.insert(enabledPlugins.substr(ii_old)); + parse_settings(settings["EnabledPlugins"], m_setEnabledPlugins); } if (settings.find("Database") != settings.end()) { @@ -92,6 +73,44 @@ void CMiddleWare::LoadSettings(const std::string& pPath) { throw std::string("No database plugin is selected."); } + set_enabled_plugins_t::iterator it_p; + for (it_p = m_setEnabledPlugins.begin(); it_p != m_setEnabledPlugins.end(); it_p++) + { + if (settings.find(*it_p) != settings.end()) + { + set_reporters_t reporters; + parse_settings(settings[*it_p], reporters); + m_mapPlugin2Reporters[*it_p] = reporters; + } + } +} + +void CMiddleWare::DebugDump2Report(const std::string& pDebugDumpDir, CReporter::report_t& pReport) +{ + CDebugDump dd; + dd.Open(pDebugDumpDir); + dd.LoadText(FILENAME_ARCHITECTURE, pReport.m_sArchitecture); + dd.LoadText(FILENAME_KERNEL, pReport.m_sKernel); + dd.LoadText(FILENAME_PACKAGE, pReport.m_sPackage); + dd.LoadText(FILENAME_EXECUTABLE, pReport.m_sExecutable); + dd.LoadText(FILENAME_CMDLINE, pReport.m_sCmdLine); + + if (dd.Exist(FILENAME_TEXTDATA1)) + { + dd.LoadText(FILENAME_TEXTDATA1, pReport.m_sTextData1); + } + if (dd.Exist(FILENAME_TEXTDATA2)) + { + dd.LoadText(FILENAME_TEXTDATA2, pReport.m_sTextData2); + } + if (dd.Exist(FILENAME_BINARYDATA1)) + { + pReport.m_bBinaryData1 = pDebugDumpDir + "/" + FILENAME_BINARYDATA1; + } + if (dd.Exist(FILENAME_BINARYDATA2)) + { + pReport.m_bBinaryData2 = pDebugDumpDir + "/" + FILENAME_BINARYDATA2; + } } void CMiddleWare::RegisterPlugin(const std::string& pName) @@ -105,20 +124,61 @@ void CMiddleWare::UnRegisterPlugin(const std::string& pName) } -std::string CMiddleWare::GetLocalUUIDLanguage(const std::string& pLanguage, const std::string& pDebugDumpPath) +std::string CMiddleWare::GetLocalUUIDLanguage(const std::string& pLanguage, + const std::string& pDebugDumpDir) +{ + CLanguage* language = m_pPluginManager->GetLanguage(pLanguage); + return language->GetLocalUUID(pDebugDumpDir); +} + +std::string CMiddleWare::GetLocalUUIDApplication(const std::string& pApplication, + const std::string& pDebugDumpDir) +{ + CApplication* application = m_pPluginManager->GetApplication(pApplication); + return application->GetLocalUUID(pDebugDumpDir); +} + + +void CMiddleWare::CreateReportLanguage(const std::string& pLanguage, + const std::string& pDebugDumpDir) { CLanguage* language = m_pPluginManager->GetLanguage(pLanguage); - return language->GetLocalUUID(pDebugDumpPath); + return language->CreateReport(pDebugDumpDir); } -std::string CMiddleWare::GetLocalUUIDApplication(const std::string& pApplication, const std::string& pDebugDumpPath) +void CMiddleWare::CreateReportApplication(const std::string& pApplication, + const std::string& pDebugDumpDir) { CApplication* application = m_pPluginManager->GetApplication(pApplication); - return application->GetLocalUUID(pDebugDumpPath); + return application->CreateReport(pDebugDumpDir); } -void CMiddleWare::GetReport(const std::string& pUUID, const std::string& pUID) +void CMiddleWare::CreateReport(const std::string& pDebugDumpDir, + crash_report_t& pCrashReport) +{ + CDebugDump dd; + dd.Open(pDebugDumpDir); + if (dd.Exist(FILENAME_APPLICATION)) + { + std::string application; + dd.LoadText(FILENAME_APPLICATION, application); + pCrashReport.m_sPlugin2ReportersName = application; + CreateReportApplication(application, pDebugDumpDir); + } + if (dd.Exist(FILENAME_LANGUAGE)) + { + std::string language; + dd.LoadText(FILENAME_LANGUAGE, language); + pCrashReport.m_sPlugin2ReportersName = language; + CreateReportLanguage(language, pDebugDumpDir); + } + DebugDump2Report(pDebugDumpDir, pCrashReport.m_Report); +} + +void CMiddleWare::CreateReport(const std::string& pUUID, + const std::string& pUID, + crash_report_t& pCrashReport) { CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase); database_row_t row; @@ -129,12 +189,30 @@ void CMiddleWare::GetReport(const std::string& pUUID, const std::string& pUID) { throw std::string("CMiddleWare::GetReport(): UUID '"+pUUID+"' is not in database."); } - // TODO: finish this + pCrashReport.m_sUUID = pUUID; + pCrashReport.m_sUID = pUID; + CreateReport(row.m_sDebugDumpPath, pCrashReport); } -int CMiddleWare::Report(const std::string& pReport) +void CMiddleWare::Report(const crash_report_t& pCrashReport) { - // TODO: write this + std::string plugin2ReportersName = pCrashReport.m_sPlugin2ReportersName; + if (m_mapPlugin2Reporters.find(plugin2ReportersName) != m_mapPlugin2Reporters.end()) + { + set_reporters_t::iterator it_r; + for (it_r = m_mapPlugin2Reporters[plugin2ReportersName].begin(); + it_r != m_mapPlugin2Reporters[plugin2ReportersName].end(); + it_r++) + { + CReporter* reporter = m_pPluginManager->GetReporter(*it_r); + reporter->Report(pCrashReport.m_Report); + } + } + + CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase); + database->Connect(); + database->SetReported(pCrashReport.m_sUUID, pCrashReport.m_sUID); + database->DisConnect(); } int CMiddleWare::SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& pCrashInfo) @@ -145,11 +223,13 @@ int CMiddleWare::SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& std::string UID; std::string package; std::string executable; + std::string time; CDebugDump dd; dd.Open(pDebugDumpPath); dd.LoadText(FILENAME_PACKAGE, package); + dd.LoadText(FILENAME_TIME, time); if (package == "" || m_setBlackList.find(package.substr(0, package.find("-"))) != m_setBlackList.end()) @@ -158,20 +238,18 @@ int CMiddleWare::SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& return 0; } + if (dd.Exist(FILENAME_APPLICATION)) + { + std::string application; + dd.LoadText(FILENAME_APPLICATION, application); + UUID = GetLocalUUIDApplication(application, pDebugDumpPath); + } if (dd.Exist(FILENAME_LANGUAGE)) { std::string language; dd.LoadText(FILENAME_LANGUAGE, language); UUID = GetLocalUUIDLanguage(language, pDebugDumpPath); } - else if (0) - { - // TODO: how to get UUID from app? - } - else - { - throw std::string("CMiddleWare::SaveDebugDumpToDataBase(): Can not get UUID."); - } if (UUID == "") { throw std::string("CMiddleWare::SaveDebugDumpToDataBase(): Wrong UUID."); @@ -182,7 +260,7 @@ int CMiddleWare::SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& database_row_t row; database->Connect(); - database->Insert(UUID, UID, pDebugDumpPath); + database->Insert(UUID, UID, pDebugDumpPath, time); row = database->GetUUIDData(UUID, UID); database->DisConnect(); @@ -201,6 +279,7 @@ int CMiddleWare::SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& pCrashInfo.m_sCount = row.m_sCount; pCrashInfo.m_sExecutable = executable; pCrashInfo.m_sPackage = package; + pCrashInfo.m_sTime = row.m_sTime; return 1; } diff --git a/lib/MiddleWare/MiddleWare.h b/lib/MiddleWare/MiddleWare.h index b9cf8b65..71c85ef0 100644 --- a/lib/MiddleWare/MiddleWare.h +++ b/lib/MiddleWare/MiddleWare.h @@ -31,33 +31,58 @@ class CMiddleWare { - private: + public: + + typedef struct SCrashInfo + { + std::string m_sUUID; + std::string m_sUID; + std::string m_sCount; + std::string m_sExecutable; + std::string m_sPackage; + std::string m_sTime; + } crash_info_t; + + typedef struct SCrashReport + { + std::string m_sUUID; + std::string m_sUID; + std::string m_sPlugin2ReportersName; + CReporter::report_t m_Report; + } crash_report_t; + + typedef std::vector<crash_info_t> vector_crash_infos_t; - typedef std::set<std::string> set_blacklist_t; - typedef std::set<std::string> set_enabled_plugins_t; + private: + typedef set_settings_t set_blacklist_t; + typedef set_settings_t set_enabled_plugins_t; + typedef set_settings_t set_reporters_t; + typedef std::map<std::string, set_reporters_t> map_plugin2reporters_t; CPluginManager* m_pPluginManager; set_blacklist_t m_setBlackList; set_enabled_plugins_t m_setEnabledPlugins; std::string m_sDatabase; + map_plugin2reporters_t m_mapPlugin2Reporters; + std::string GetLocalUUIDLanguage(const std::string& pLanguage, const std::string& pDebugDumpDir); + void CreateReportLanguage(const std::string& pLanguage, + const std::string& pDebugDumpDir); std::string GetLocalUUIDApplication(const std::string& pApplication, - const std::string& pDebugDumpPath); + const std::string& pDebugDumpDir); + void CreateReportApplication(const std::string& pApplication, + const std::string& pDebugDumpDir); + void LoadSettings(const std::string& pPath); - public: - typedef struct SCrashInfo - { - std::string m_sUUID; - std::string m_sUID; - std::string m_sCount; - std::string m_sExecutable; - std::string m_sPackage; - } crash_info_t; + void DebugDump2Report(const std::string& pDebugDumpDir, + CReporter::report_t& pReport); + void CreateReport(const std::string& pDebugDumpDir, + crash_report_t& pReport); - typedef std::vector<crash_info_t> vector_crash_infos_t; + public: CMiddleWare(const std::string& pPlugisConfDir, const std::string& pPlugisLibDir, @@ -68,11 +93,12 @@ class CMiddleWare void RegisterPlugin(const std::string& pName); void UnRegisterPlugin(const std::string& pName); - void GetReport(const std::string& pUUID, const std::string& pUID); - int Report(const std::string& pReport); + void CreateReport(const std::string& pUUID, + const std::string& pUID, + crash_report_t& pReport); + void Report(const crash_report_t& pReport); int SaveDebugDump(const std::string& pDebugDumpPath, crash_info_t& pCrashInfo); - vector_crash_infos_t GetCrashInfos(const std::string& pUID); }; diff --git a/lib/MiddleWare/Reporter.h b/lib/MiddleWare/Reporter.h index f1493f5b..8f23065b 100644 --- a/lib/MiddleWare/Reporter.h +++ b/lib/MiddleWare/Reporter.h @@ -28,8 +28,21 @@ class CReporter : public CPlugin { public: + typedef struct SReport + { + std::string m_sArchitecture; + std::string m_sKernel; + std::string m_sExecutable; + std::string m_sCmdLine; + std::string m_sPackage; + std::string m_sTextData1; + std::string m_sTextData2; + std::string m_bBinaryData1; + std::string m_bBinaryData2; + } report_t; + virtual ~CReporter() {} - virtual void Report(const std::string& pDebugDumpPath) = 0; + virtual void Report(const report_t& pReport) = 0; }; #endif /* REPORTER_H_ */ diff --git a/lib/MiddleWare/Settings.cpp b/lib/MiddleWare/Settings.cpp index 413820bd..92e22eab 100644 --- a/lib/MiddleWare/Settings.cpp +++ b/lib/MiddleWare/Settings.cpp @@ -97,3 +97,16 @@ void save_settings(const std::string& path, const map_settings_t& settings) throw std::string("save_settings(): Cannot write configuration file '"+path+"'."); } } + +void parse_settings(const std::string& pLine, set_settings_t& settings) +{ + std::string::size_type ii_old = 0, ii_new = 0; + ii_new = pLine.find(","); + while (ii_new != std::string::npos) + { + settings.insert(pLine.substr(ii_old, ii_new - ii_old)); + ii_old = ii_new + 1; + ii_new = pLine.find(",",ii_old); + } + settings.insert(pLine.substr(ii_old)); +} diff --git a/lib/MiddleWare/Settings.h b/lib/MiddleWare/Settings.h index a427f1b5..46d50a5b 100644 --- a/lib/MiddleWare/Settings.h +++ b/lib/MiddleWare/Settings.h @@ -25,10 +25,13 @@ #include "Settings.h" #include <string> #include <map> +#include <set> typedef std::map<std::string, std::string> map_settings_t; +typedef std::set<std::string> set_settings_t; void load_settings(const std::string& path, map_settings_t& settings); void save_settings(const std::string& path, const map_settings_t& settings); +void parse_settings(const std::string& pLine, set_settings_t& settings); #endif /* SETTINGSFUNC_H_ */ diff --git a/lib/MiddleWare/test.cpp b/lib/MiddleWare/test.cpp index 8424aa99..57c55068 100644 --- a/lib/MiddleWare/test.cpp +++ b/lib/MiddleWare/test.cpp @@ -35,23 +35,33 @@ int main(int argc, char** argv) CMiddleWare middleWare(PLUGINS_CONF_DIR, PLUGINS_LIB_DIR, std::string(CONF_DIR) + "/CrashCatcher.conf"); + /* Create DebugDump */ CDebugDump dd; - char pid[100]; sprintf(pid, "%d", getpid()); - - dd.Create(std::string(DEBUG_DUMPS_DIR)+"/"+pid, pid); + dd.Create(std::string(DEBUG_DUMPS_DIR)+"/"+pid); + dd.SaveProc(pid); + dd.SavePackage(); dd.SaveText(FILENAME_LANGUAGE, "CCpp"); dd.SaveBinary(FILENAME_BINARYDATA1, "ass0-9as", sizeof("ass0-9as")); + /* Try to save it into DB */ CMiddleWare::crash_info_t info; - middleWare.SaveDebugDump(std::string(DEBUG_DUMPS_DIR)+"/"+pid, info); - - std::cout << "Application Crashed! " << - info.m_sPackage << ": " << - info.m_sExecutable << "(" << - info.m_sCount << ")" << std::endl; + if (middleWare.SaveDebugDump(std::string(DEBUG_DUMPS_DIR)+"/"+pid, info)) + { + std::cout << "Application Crashed! " << + "(" << info.m_sTime << " [" << info.m_sCount << "]) " << + info.m_sPackage << ": " << + info.m_sExecutable << std::endl; + /* Get Report, so user can change data (remove private stuff) + * If we do not want user interaction, just send data immediately + */ + CMiddleWare::crash_report_t crashReport; + middleWare.CreateReport(info.m_sUUID, info.m_sUID, crashReport); + /* Report crash */ + middleWare.Report(crashReport); + } } catch (std::string sError) { diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index ce65acdc..657f9ac9 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -26,31 +26,49 @@ #include <sstream> #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" -#define CORE_PATTERN CCPP_HOOK_PATH" %p %t %s" +#define CORE_PATTERN CCPP_HOOK_PATH" %p %s" CLanguageCCpp::CLanguageCCpp() : m_bMemoryMap(false) {} -std::string CLanguageCCpp::GetLocalUUID(const std::string& pDebugDumpPath) +std::string CLanguageCCpp::GetLocalUUID(const std::string& pDebugDumpDir) { std::stringstream ss; char* core; unsigned int size; CDebugDump dd; - dd.Open(pDebugDumpPath); + dd.Open(pDebugDumpDir); dd.LoadBinary(FILENAME_BINARYDATA1, &core, &size); - // TODO: write proper handler + // TODO: compute local UUID ss << size; return ss.str(); } +std::string CLanguageCCpp::GetGlobalUUID(const std::string& pDebugDumpDir) +{ + std::stringstream ss; + CDebugDump dd; + std::string backtrace; + dd.Open(pDebugDumpDir); + dd.LoadText(FILENAME_TEXTDATA1, backtrace); + + // TODO: compute global UUID + ss << backtrace.length(); + return ss.str(); +} -std::string CLanguageCCpp::GetReport(const std::string& pDebugDumpPath) +void CLanguageCCpp::CreateReport(const std::string& pDebugDumpDir) { - // TODO: install or mount debug-infos - // TODO: - return "report"; + CDebugDump dd; + dd.Open(pDebugDumpDir); + + // TODO: install or mount debug-infos, gun gdb/archer and get backtrace + dd.SaveText(FILENAME_TEXTDATA1, "backtrace of the crashed C/C++ application"); + if (m_bMemoryMap) + { + dd.SaveText(FILENAME_TEXTDATA2, "memory map of the crashed C/C++ application"); + } } void CLanguageCCpp::Init() diff --git a/lib/Plugins/CCpp.h b/lib/Plugins/CCpp.h index ef491d58..e1c2015e 100644 --- a/lib/Plugins/CCpp.h +++ b/lib/Plugins/CCpp.h @@ -35,8 +35,9 @@ class CLanguageCCpp : public CLanguage public: CLanguageCCpp(); virtual ~CLanguageCCpp() {} - std::string GetLocalUUID(const std::string& pDebugDumpPath); - std::string GetReport(const std::string& pDebugDumpPath); + std::string GetLocalUUID(const std::string& pDebugDumpDir); + std::string GetGlobalUUID(const std::string& pDebugDumpDir); + void CreateReport(const std::string& pDebugDumpDir); void Init(); void DeInit(); void SetSettings(const map_settings_t& pSettings); diff --git a/lib/Plugins/Mailx.cpp b/lib/Plugins/Mailx.cpp index 809dbd23..cb26e398 100644 --- a/lib/Plugins/Mailx.cpp +++ b/lib/Plugins/Mailx.cpp @@ -21,23 +21,27 @@ #include "Mailx.h" #include <stdio.h> +#include <sstream> +#include "DebugDump.h" -#define MAILX_COMMAND "mailx" -#define MAILX_SUBJECT "CrashCatcher automated bug report" +#define MAILX_COMMAND "/bin/mailx" +#define MAILX_SUBJECT "\"CrashCatcher automated bug report\"" CMailx::CMailx() : m_sEmailFrom(""), m_sEmailTo(""), - m_sParameters() + m_sParameters(""), + m_sAttachments("") {} void CMailx::SendEmail(const std::string& pText) { FILE* command; - std::string mailx_command = MAILX_COMMAND + m_sParameters + + std::string mailx_command = MAILX_COMMAND + m_sAttachments + + " " + m_sParameters + " -s " + MAILX_SUBJECT + - " -r " + m_sEmailTo + " " + m_sEmailFrom; + " -r " + m_sEmailFrom + " " + m_sEmailTo; command = popen(mailx_command.c_str(), "w"); if (!command) @@ -52,9 +56,57 @@ void CMailx::SendEmail(const std::string& pText) } -void CMailx::Report(const std::string& pDebugDumpPath) +void CMailx::Report(const report_t& pReport) { - SendEmail("Nejakej zbesilej report."); + std::stringstream ss; + + 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; + } + ss << "Binary reports" << std::endl; + ss << "==============" << std::endl; + ss << "See the attachment[s]" << std::endl; + + if (pReport.m_bBinaryData1 != "") + { + m_sAttachments = " -a " + pReport.m_bBinaryData1; + } + if (pReport.m_bBinaryData2 != "") + { + m_sAttachments = " -a " + pReport.m_bBinaryData2; + } + + SendEmail(ss.str()); } void CMailx::SetSettings(const map_settings_t& pSettings) @@ -65,7 +117,7 @@ void CMailx::SetSettings(const map_settings_t& pSettings) } if (pSettings.find("Email_To")!= pSettings.end()) { - m_sEmailFrom = pSettings.find("Email_To")->second; + m_sEmailTo = pSettings.find("Email_To")->second; } if (pSettings.find("Parameters")!= pSettings.end()) { diff --git a/lib/Plugins/Mailx.h b/lib/Plugins/Mailx.h index 4a1d61b3..3c54feb6 100644 --- a/lib/Plugins/Mailx.h +++ b/lib/Plugins/Mailx.h @@ -33,6 +33,7 @@ class CMailx : public CReporter std::string m_sEmailFrom; std::string m_sEmailTo; std::string m_sParameters; + std::string m_sAttachments; void SendEmail(const std::string& pText); @@ -43,7 +44,7 @@ class CMailx : public CReporter void DeInit() {} void SetSettings(const map_settings_t& pSettings); - void Report(const std::string& pDebugDumpPath); + void Report(const report_t& pReport); }; diff --git a/lib/Plugins/SQLite3.cpp b/lib/Plugins/SQLite3.cpp index b28a866c..c6cf8f4c 100644 --- a/lib/Plugins/SQLite3.cpp +++ b/lib/Plugins/SQLite3.cpp @@ -85,6 +85,8 @@ void CSQLite3::GetTable(const std::string& pCommand, vector_database_rows_t& pTa break; case 4: row.m_sReported = table[jj + ncol]; break; + case 5: row.m_sTime = table[jj + ncol]; + break; default: break; } @@ -125,11 +127,12 @@ void CSQLite3::Create() Exec("CREATE TABLE "TABLE_NAME" (" DATABASE_COLUMN_UUID" VARCHAR NOT NULL," - DATABASE_COLUMN_UID" VARCHAR(64) NOT NULL," + DATABASE_COLUMN_UID" VARCHAR NOT NULL," DATABASE_COLUMN_DEBUG_DUMP_PATH" VARCHAR NOT NULL," - DATABASE_COLUMN_COUNT" INT(10) NOT NULL DEFAULT 1," - DATABASE_COLUMN_REPORTED" INT(10) NOT NULL DEFAULT 0," - "PRIMARY KEY (UUID, UID));"); + DATABASE_COLUMN_COUNT" INT NOT NULL DEFAULT 1," + DATABASE_COLUMN_REPORTED" INT NOT NULL DEFAULT 0," + DATABASE_COLUMN_TIME" VARCHAR NOT NULL DEFAULT 0," + "PRIMARY KEY ("DATABASE_COLUMN_UUID","DATABASE_COLUMN_UID"));"); } void CSQLite3::DisConnect() @@ -139,23 +142,27 @@ void CSQLite3::DisConnect() void CSQLite3::Insert(const std::string& pUUID, const std::string& pUID, - const std::string& pDebugDumpPath) + const std::string& pDebugDumpPath, + const std::string& pTime) { if (!Exist(pUUID, pUID)) { Exec("INSERT INTO "TABLE_NAME"(" DATABASE_COLUMN_UUID"," DATABASE_COLUMN_UID"," - DATABASE_COLUMN_DEBUG_DUMP_PATH")" + DATABASE_COLUMN_DEBUG_DUMP_PATH"," + DATABASE_COLUMN_TIME")" " VALUES ('"+pUUID+"'," "'"+pUID+"'," - "'"+pDebugDumpPath+"'" + "'"+pDebugDumpPath+"'," + "'"+pTime+"'" ");"); } else { Exec("UPDATE "TABLE_NAME" " - "SET "DATABASE_COLUMN_COUNT" = "DATABASE_COLUMN_COUNT" + 1 " + "SET "DATABASE_COLUMN_COUNT" = "DATABASE_COLUMN_COUNT" + 1, " + DATABASE_COLUMN_TIME" = '"+pTime+"' " "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"' " "AND "DATABASE_COLUMN_UID" = '"+pUID+"';"); } diff --git a/lib/Plugins/SQLite3.h b/lib/Plugins/SQLite3.h index 31fd8ab8..03ef88dd 100644 --- a/lib/Plugins/SQLite3.h +++ b/lib/Plugins/SQLite3.h @@ -47,7 +47,8 @@ class CSQLite3 : public CDatabase void Insert(const std::string& pUUID, const std::string& pUID, - const std::string& pDebugDumpPath); + const std::string& pDebugDumpPath, + const std::string& pTime); void Delete(const std::string& pUUID, const std::string& pUID); void SetReported(const std::string& pUUID, const std::string& pUID); diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp index e0f88c4c..09e65aea 100644 --- a/lib/Utils/DebugDump.cpp +++ b/lib/Utils/DebugDump.cpp @@ -79,13 +79,6 @@ void CDebugDump::Create(const std::string& pDir) SaveTime(); } -void CDebugDump::Create(const std::string& pDir, const std::string& pPID) -{ - Create(pDir); - SaveProc(pPID); -} - - void CDebugDump::Delete(const std::string& pDir) { if (!ExistFileDir(pDir)) @@ -253,12 +246,6 @@ void CDebugDump::SaveProc(const std::string& pPID) SaveText(FILENAME_EXECUTABLE, executable); } - CPackages packages; - while (!packages.SearchFile(executable)) {} - while (!packages.GetStatus()) {} - std::string package = packages.GetSearchFileReply(); - - SaveText(FILENAME_PACKAGE, package); path = "/proc/"+pPID+"/status"; std::string uid = ""; @@ -273,4 +260,21 @@ void CDebugDump::SaveProc(const std::string& pPID) ii++; } SaveText(FILENAME_UID, uid); + + path = "/proc/"+pPID+"/cmdline"; + LoadTextFile(path, data); + SaveText(FILENAME_CMDLINE, data); +} + +void CDebugDump::SavePackage() +{ + std::string executable; + std::string package = ""; + if (Exist(FILENAME_EXECUTABLE)) + { + CPackages packages; + LoadText(FILENAME_EXECUTABLE, executable); + package = packages.SearchFile("/usr/sbin/acpid"); + } + SaveText(FILENAME_PACKAGE, package); } diff --git a/lib/Utils/DebugDump.h b/lib/Utils/DebugDump.h index 11574e95..f7e740d7 100644 --- a/lib/Utils/DebugDump.h +++ b/lib/Utils/DebugDump.h @@ -28,14 +28,16 @@ #define FILENAME_ARCHITECTURE "architecture" #define FILENAME_KERNEL "kernel" #define FILENAME_EXECUTABLE "executable" +#define FILENAME_CMDLINE "cmdline" #define FILENAME_TIME "time" #define FILENAME_UID "uid" #define FILENAME_PACKAGE "package" -#define FILENAME_HASH "hash" #define FILENAME_LANGUAGE "language" #define FILENAME_APPLICATION "application" #define FILENAME_TEXTDATA1 "text_data1" +#define FILENAME_TEXTDATA2 "text_data2" #define FILENAME_BINARYDATA1 "binary_data1" +#define FILENAME_BINARYDATA2 "binary_data2" class CDebugDump { @@ -44,7 +46,6 @@ class CDebugDump void SaveEnvironment(); void SaveTime(); - void SaveProc(const std::string& pPID); void LoadTextFile(const std::string& pName, std::string& pData); void LoadBinaryFile(const std::string& pName, char** pData, unsigned int* pSize); @@ -58,7 +59,9 @@ class CDebugDump CDebugDump(); void Open(const std::string& pDir); void Create(const std::string& pDir); - void Create(const std::string& pDir, const std::string& pPID); + void SaveProc(const std::string& pPID); + void SavePackage(); + void Delete(const std::string& pDir); bool Exist(const std::string& pFileName); diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index 2b47b1ee..cc98223d 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -1,8 +1,8 @@ lib_LTLIBRARIES = libUtils.la libUtils_la_SOURCES = DebugDump.cpp DebugDump.h Packages.cpp Packages.h libUtils_la_LDFLAGS = -version-info 0:1:0 -libUtils_la_CPPFLAGS = $(PACKAGEKIT_GLIB_CFLAGS) -libUtils_la_LIBADD = $(PACKAGEKIT_GLIB_LIBS) +libUtils_la_CPPFLAGS = $(PACKAGEKIT_GLIB_CFLAGS) $(RPM_CFLAGS) +libUtils_la_LIBADD = $(PACKAGEKIT_GLIB_LIBS) $(RPM_LIBS) install-data-local: $(mkdir_p) '$(DEBUG_DUMPS_DIR)'
\ No newline at end of file diff --git a/lib/Utils/Packages.cpp b/lib/Utils/Packages.cpp index ed406b03..654967df 100644 --- a/lib/Utils/Packages.cpp +++ b/lib/Utils/Packages.cpp @@ -20,6 +20,11 @@ */ #include "Packages.h" +#include <rpm/rpmts.h> +#include <rpm/rpmdb.h> +#include <rpm/rpmcli.h> +#include <sstream> + CPackages::CPackages() : m_pPkClient(NULL), @@ -35,26 +40,33 @@ CPackages::~CPackages() g_object_unref(m_pPkClient); } -bool CPackages::SearchFile(const std::string& pPath) +std::string CPackages::SearchFile(const std::string& pPath) { - if (m_bBusy) + std::stringstream ss; + char *argv[] = {(char*)""}; + poptContext context = rpmcliInit(0, argv, NULL); + rpmts ts = rpmtsCreate(); + rpmdbMatchIterator iter = rpmtsInitIterator(ts, RPMTAG_BASENAMES, "/usr/sbin/acpid", 0); + Header header; + char* nerv = NULL; + + if ((header = rpmdbNextIterator(iter)) != NULL) { - return false; + nerv = headerGetNEVR(header, NULL); } - m_bBusy = true; - GError *error = NULL; - gboolean ret = pk_client_search_file (m_pPkClient, - pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), - pPath.c_str(), - &error); - if (ret == FALSE) + + headerFree(header); + rpmcliFini(context); + rpmtsFree(ts); + + if (nerv != NULL) { - std::string err = error->message; - g_error_free(error); - error = NULL; - throw std::string("CPackages::SearchFile(): ") + err; + std::string ret = nerv; + free(nerv); + return ret; } - return true; + + return ""; } bool CPackages::Install(const std::string& pPackage) @@ -63,7 +75,7 @@ bool CPackages::Install(const std::string& pPackage) } -bool CPackages::GetStatus() +bool CPackages::GetInstallationStatus() { GError *error = NULL; PkStatusEnum status; @@ -81,32 +93,3 @@ bool CPackages::GetStatus() } return true; } - -std::string CPackages::GetSearchFileReply() -{ - GError *error = NULL; - std::string packageName = ""; - gchar *package; - gboolean ret = pk_client_get_package (m_pPkClient, &package, &error); - if (ret == FALSE) - { - std::string err = error->message; - g_error_free(error); - if (err == "No package data available") - { - return ""; - } - throw std::string("CPackages::SearchFile(): ") + err; - } - packageName = package; - packageName[packageName.find(";")] = '-'; - packageName = packageName.substr(0, packageName.find(";")); - - m_bBusy = false; - return packageName; -} - -bool CPackages::GetInstallReply() -{ - // TODO: write this -} diff --git a/lib/Utils/Packages.h b/lib/Utils/Packages.h index 2228acc0..9874dd7f 100644 --- a/lib/Utils/Packages.h +++ b/lib/Utils/Packages.h @@ -36,13 +36,10 @@ class CPackages public: CPackages(); ~CPackages(); - bool SearchFile(const std::string& pPath); - bool Install(const std::string& pPackage); - bool GetStatus(); - - std::string GetSearchFileReply(); - bool GetInstallReply(); + std::string SearchFile(const std::string& pPath); + bool Install(const std::string& pPackage); + bool GetInstallationStatus(); }; #endif /* PACKAGES_H_ */ diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index 6914e310..ba82c286 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -50,17 +50,12 @@ int main(int argc, char** argv) { char path[PATH_MAX]; CDebugDump dd; - time_t t = time(NULL); - if (((time_t) -1) == t) - { - fprintf(stderr, "%s: cannot get local time.\n", program_name); - perror(""); - return -4; - } - snprintf(path, sizeof(path), "%s/ccpp-%d-%s", DEBUG_DUMPS_DIR, t, pid); + snprintf(path, sizeof(path), "%s/ccpp-%ld-%s", DEBUG_DUMPS_DIR, time(NULL), pid); - dd.Create(path, pid); + dd.Create(path); + dd.SaveProc(pid); dd.SaveText(FILENAME_LANGUAGE, "CCpp"); + dd.SavePackage(); int size = CORESTEP*sizeof(char); int ii = 0; @@ -68,7 +63,7 @@ int main(int argc, char** argv) char* core = NULL; if ((core = (char*)malloc(size)) == NULL) { - fprintf(stderr, "%s: not enaught memory.\n", program_name); + fprintf(stderr, "%s: not enough memory.\n", program_name); perror(""); return -3; } @@ -79,7 +74,7 @@ int main(int argc, char** argv) size *= CORESTEP*sizeof(char); if ((core = (char*)realloc(core, size)) == NULL) { - fprintf(stderr, "%s: not enaught memory.\n", program_name); + fprintf(stderr, "%s: not enough memory.\n", program_name); perror(""); return -3; } |