diff options
| author | Nikola Pajkovsky <npajkovs@redhat.com> | 2010-08-30 19:28:08 +0200 |
|---|---|---|
| committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-08-30 19:28:08 +0200 |
| commit | eb6a80fe031f648d11344ed912e9a5e1e722545e (patch) | |
| tree | 837100d82635c022447ff1821f3dcdab4278e45e | |
| parent | dac728745922a717db05f2e8dcbe6c533dc0df6f (diff) | |
get rid of CDebugDump class
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
| -rw-r--r-- | inc/debug_dump.h | 72 | ||||
| -rw-r--r-- | lib/plugins/CCpp.cpp | 174 | ||||
| -rw-r--r-- | lib/plugins/Kerneloops.cpp | 11 | ||||
| -rw-r--r-- | lib/plugins/KerneloopsScanner.cpp | 18 | ||||
| -rw-r--r-- | lib/plugins/Python.cpp | 16 | ||||
| -rw-r--r-- | lib/plugins/RunApp.cpp | 9 | ||||
| -rw-r--r-- | lib/plugins/SOSreport.cpp | 9 | ||||
| -rw-r--r-- | lib/utils/DebugDump.cpp | 320 | ||||
| -rw-r--r-- | src/daemon/MiddleWare.cpp | 230 | ||||
| -rw-r--r-- | src/daemon/dumpsocket.cpp | 24 | ||||
| -rw-r--r-- | src/hooks/abrt-hook-ccpp.cpp | 22 |
11 files changed, 466 insertions, 439 deletions
diff --git a/inc/debug_dump.h b/inc/debug_dump.h index 2e04d780..60cddd7e 100644 --- a/inc/debug_dump.h +++ b/inc/debug_dump.h @@ -23,57 +23,33 @@ #define DEBUGDUMP_H_ #ifdef __cplusplus - -#include <string> - -class CDebugDump -{ - private: - std::string m_sDebugDumpDir; - DIR* m_pGetNextFileDir; - bool m_bOpened; - bool m_bLocked; - uid_t m_uid; - gid_t m_gid; - - void Lock(); - void UnLock(); - - public: - CDebugDump(); - ~CDebugDump(); - - bool Open(const char *pDir); - bool Create(const char *pDir, uid_t uid); - void Delete(); - void Close(); - - bool Exist(const char* pFileName); - - void LoadText(const char* pName, std::string& pData); - - void SaveText(const char* pName, const char *pData); - void SaveBinary(const char* pName, const char* pData, unsigned pSize); - - bool InitGetNextFile(); - /* Pointers may be NULL */ - bool GetNextFile(std::string *short_name, std::string *full_name); - - const char *Directory() const { return m_sDebugDumpDir.c_str(); } -}; - -#endif /* __cplusplus */ - - -#ifdef __cplusplus extern "C" { #endif -/** - * Deletes particular debugdump directory. - * @param pDebugDumpDir A debugdump directory. - */ -void delete_debug_dump_dir(const char *pDebugDumpDir); +typedef struct dump_dir { + char *dd_dir; + DIR *next_dir; + int opened; + int locked; + uid_t uid; + gid_t gid; +} dump_dir_t; + +dump_dir_t* dd_init(void); +void dd_close(dump_dir_t *dd); + +int dd_opendir(dump_dir_t *dd, const char *dir); +int dd_exist(dump_dir_t *dd, const char *path); +int dd_create(dump_dir_t *dd, const char *dir, uid_t uid); +int dd_init_next_file(dump_dir_t *dd); +int dd_get_next_file(dump_dir_t *dd, char **short_name, char **full_name); + +char* dd_loadtxt(const dump_dir_t *dd, const char* name); +void dd_savetxt(dump_dir_t *dd, const char *name, const char *data); +void dd_savebin(dump_dir_t* dd, const char* name, const char* data, unsigned size); +void dd_delete(dump_dir_t *dd); + +void delete_debug_dump_dir(const char *dd_dir); #ifdef __cplusplus } diff --git a/lib/plugins/CCpp.cpp b/lib/plugins/CCpp.cpp index 2ecf9308..7665cad3 100644 --- a/lib/plugins/CCpp.cpp +++ b/lib/plugins/CCpp.cpp @@ -186,18 +186,17 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs { update_client(_("Generating backtrace")); - string UID; - string executable; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); - return false; + return NULL; } - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(CD_UID, UID); - dd.Close(); + char *uid = dd_loadtxt(dd, CD_UID); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + dd_close(dd); // Workaround for // http://sourceware.org/bugzilla/show_bug.cgi?id=9622 @@ -248,7 +247,8 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs * BINARY_FILE if it is newer (to at least avoid gdb complaining). */ args[4] = (char*)"-ex"; - args[5] = xasprintf("file %s", executable.c_str()); + args[5] = xasprintf("file %s", executable); + free(executable); args[6] = (char*)"-ex"; args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, pDebugDumpDir); @@ -277,7 +277,7 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs while (1) { args[9] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full); - bt = exec_vp(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 1, NULL); + bt = exec_vp(args, xatoi_u(uid), /*redirect_stderr:*/ 1, NULL); if (bt && (bt_depth <= 64 || strlen(bt) < 256*1024)) { free(args[9]); @@ -300,6 +300,7 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs free(bt); free(args[9]); } + free(uid); free(args[5]); free(args[7]); return bt; @@ -334,16 +335,16 @@ static void GetIndependentBuildIdPC(const char *unstrip_n_output, static char* run_unstrip_n(const char *pDebugDumpDir) { - string UID; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return NULL; } - dd.LoadText(CD_UID, UID); - dd.Close(); + char *uid = dd_loadtxt(dd, CD_UID); + dd_close(dd); char* args[4]; args[0] = (char*)"eu-unstrip"; @@ -351,7 +352,8 @@ static char* run_unstrip_n(const char *pDebugDumpDir) args[2] = (char*)"-n"; args[3] = NULL; - char *out = exec_vp(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 0, NULL); + char *out = exec_vp(args, xatoi_u(uid), /*redirect_stderr:*/ 0, NULL); + free(uid); free(args[1]); @@ -527,18 +529,17 @@ static void trim_debuginfo_cache(unsigned max_mb) string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) { - string executable; - string package; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - dd.Close(); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + dd_close(dd); string independentBuildIdPC; char *unstrip_n_output = run_unstrip_n(pDebugDumpDir); @@ -551,8 +552,7 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) /* package variable has "firefox-3.5.6-1.fc11[.1]" format */ /* Remove distro suffix and maybe least significant version number */ - char *trimmed_package = xstrdup(package.c_str()); - char *p = trimmed_package; + char *p = package; while (*p) { if (*p == '.' && (p[1] < '0' || p[1] > '9')) @@ -563,7 +563,7 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) } p++; } - char *first_dot = strchr(trimmed_package, '.'); + char *first_dot = strchr(package, '.'); if (first_dot) { char *last_dot = strrchr(first_dot, '.'); @@ -576,26 +576,34 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) *last_dot = '\0'; } } - string hash_str = trimmed_package + executable + independentBuildIdPC; - free(trimmed_package); - return create_hash(hash_str.c_str()); + + char *hash_str = xasprintf("%s%s%s", package, executable, independentBuildIdPC.c_str()); + free(package); + free(executable); + + string hash = create_hash(hash_str); + free(hash_str); + + return hash; } string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) { - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - if (dd.Exist(FILENAME_GLOBAL_UUID)) + if (dd_exist(dd, FILENAME_GLOBAL_UUID)) { - string uuid; - dd.LoadText(FILENAME_GLOBAL_UUID, uuid); - dd.Close(); - return uuid; + char *uuid = dd_loadtxt(dd, FILENAME_GLOBAL_UUID); + dd_close(dd); + string ret = uuid; + free(uuid); + return ret; } else { @@ -603,13 +611,10 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) // This whole block should be deleted for Fedora 14. log(_("Getting global universal unique identification...")); - string executable; - string package; - string uid_str; - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - if (m_bBacktrace) - dd.LoadText(CD_UID, uid_str); + string backtrace_path = concat_path_file(pDebugDumpDir, FILENAME_BACKTRACE); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + char *uid_str = m_bBacktrace ? dd_loadtxt(dd, CD_UID) : xstrdup(""); string independent_backtrace; if (m_bBacktrace) @@ -641,7 +646,7 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) close(pipeout[0]); /* read side of the pipe */ /* abrt-backtrace is executed under the user's uid and gid. */ - uid_t uid = xatoi_u(uid_str.c_str()); + uid_t uid = xatoi_u(uid_str); struct passwd* pw = getpwuid(uid); gid_t gid = pw ? pw->pw_gid : uid; setgroups(1, &gid); @@ -707,12 +712,18 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) */ else { - dd.SaveText(FILENAME_RATING, "0"); + dd_savetxt(dd, FILENAME_RATING, "0"); } - dd.Close(); + dd_close(dd); + + char *hash_str = xasprintf("%s%s%s", package, executable, independent_backtrace.c_str()); + free(package); + free(executable); - string hash_base = package + executable + independent_backtrace; - return create_hash(hash_base.c_str()); + string hash = create_hash(hash_str); + free(hash_str); + + return hash; } } @@ -748,42 +759,50 @@ static bool DebuginfoCheckPolkit(uid_t uid) void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) { - string package, executable, UID; - - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return; } /* Skip remote crashes. */ - if (dd.Exist(FILENAME_REMOTE)) + if (dd_exist(dd, FILENAME_REMOTE)) { - std::string remote_str; - dd.LoadText(FILENAME_REMOTE, remote_str); - bool remote = (remote_str.find('1') != std::string::npos); + char *remote_str = dd_loadtxt(dd, FILENAME_REMOTE); + bool remote = (remote_str[0] != '1'); + free(remote_str); if (remote && !m_bBacktraceRemotes) + { + dd_close(dd); return; + } } if (!m_bBacktrace) + { + dd_close(dd); return; + } if (!force) { - bool bt_exists = dd.Exist(FILENAME_BACKTRACE); + int bt_exists = dd_exist(dd, FILENAME_BACKTRACE); if (bt_exists) + { + dd_close(dd); return; /* backtrace already exists */ + } } - dd.LoadText(FILENAME_PACKAGE, package); - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(CD_UID, UID); - dd.Close(); /* do not keep dir locked longer than needed */ + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *uid = dd_loadtxt(dd, CD_UID); + dd_close(dd); /* do not keep dir locked longer than needed */ char *build_ids = NULL; - if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(UID.c_str()))) + if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(uid))) { if (m_nDebugInfoCacheMB > 0) trim_debuginfo_cache(m_nDebugInfoCacheMB); @@ -803,22 +822,25 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) char *bt_build_ids = xasprintf("%s%s", backtrace_str, (build_ids) ? build_ids : ""); free(build_ids); - if (!dd.Open(pDebugDumpDir)) + dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return; } - dd.SaveText(FILENAME_BACKTRACE, bt_build_ids); + dd_savetxt(dd, FILENAME_BACKTRACE, bt_build_ids); free(bt_build_ids); if (m_bMemoryMap) - dd.SaveText(FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); + dd_savetxt(dd, FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); /* Compute and store UUID from the backtrace. */ char *backtrace_cpy = xstrdup(backtrace_str); struct backtrace *backtrace = backtrace_parse(backtrace_cpy, false, false); free(backtrace_cpy); + if (backtrace) { /* Get the quality of the full backtrace. */ @@ -846,9 +868,9 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) /* Compute UUID. */ struct strbuf *bt = backtrace_tree_as_str(backtrace, false); - strbuf_prepend_str(bt, executable.c_str()); - strbuf_prepend_str(bt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(bt->buf).c_str()); + strbuf_prepend_str(bt, executable); + strbuf_prepend_str(bt, package); + dd_savetxt(dd, FILENAME_GLOBAL_UUID, create_hash(bt->buf).c_str()); strbuf_free(bt); /* Compute and store backtrace rating. */ @@ -864,7 +886,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) else if (qtot < 0.8f) rating = "2"; else if (qtot < 0.9f) rating = "3"; else rating = "4"; - dd.SaveText(FILENAME_RATING, rating); + dd_savetxt(dd, FILENAME_RATING, rating); /* Get the function name from the crash frame. */ if (crash_thread) @@ -874,7 +896,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) if (abort_frame) crash_frame = abort_frame->next; if (crash_frame && crash_frame->function && 0 != strcmp(crash_frame->function, "??")) - dd.SaveText(FILENAME_CRASH_FUNCTION, crash_frame->function); + dd_savetxt(dd, FILENAME_CRASH_FUNCTION, crash_frame->function); } backtrace_free(backtrace); @@ -886,17 +908,19 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) the parser never fails, and it will be possible to get rid of the independent_backtrace and backtrace_rate_old. */ struct strbuf *ibt = independent_backtrace(backtrace_str); - strbuf_prepend_str(ibt, executable.c_str()); - strbuf_prepend_str(ibt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(ibt->buf).c_str()); + strbuf_prepend_str(ibt, executable); + strbuf_prepend_str(ibt, package); + dd_savetxt(dd, FILENAME_GLOBAL_UUID, create_hash(ibt->buf).c_str()); strbuf_free(ibt); /* Compute and store backtrace rating. */ /* Crash frame is not known so store nothing. */ - dd.SaveText(FILENAME_RATING, to_string(backtrace_rate_old(backtrace_str)).c_str()); + dd_savetxt(dd, FILENAME_RATING, to_string(backtrace_rate_old(backtrace_str)).c_str()); } + free(executable); + free(package); free(backtrace_str); - dd.Close(); + dd_close(dd); } /* diff --git a/lib/plugins/Kerneloops.cpp b/lib/plugins/Kerneloops.cpp index 2ffc2e34..f6fa2606 100644 --- a/lib/plugins/Kerneloops.cpp +++ b/lib/plugins/Kerneloops.cpp @@ -126,17 +126,18 @@ std::string CAnalyzerKerneloops::GetLocalUUID(const char *pDebugDumpDir) { VERB3 log("Getting local universal unique identification"); - std::string oops; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return std::string(""); } - dd.LoadText(FILENAME_BACKTRACE, oops); + char *oops = dd_loadtxt(dd, FILENAME_BACKTRACE); + unsigned hash = hash_oops_str(oops); + free(oops); - unsigned hash = hash_oops_str(oops.c_str()); hash &= 0x7FFFFFFF; return to_string(hash); diff --git a/lib/plugins/KerneloopsScanner.cpp b/lib/plugins/KerneloopsScanner.cpp index 8c25dff8..1621b04d 100644 --- a/lib/plugins/KerneloopsScanner.cpp +++ b/lib/plugins/KerneloopsScanner.cpp @@ -133,18 +133,18 @@ int save_oops_to_debug_dump(const vector_string_t& oopsList) char *second_line = (char*)strchr(first_line, '\n'); /* never NULL */ *second_line++ = '\0'; - CDebugDump dd; - if (dd.Create(path, /*uid:*/ 0)) + dump_dir_t *dd = dd_init(); + if (dd_create(dd, path, /*uid:*/ 0)) { - dd.SaveText(FILENAME_ANALYZER, "Kerneloops"); - dd.SaveText(FILENAME_EXECUTABLE, "kernel"); - dd.SaveText(FILENAME_KERNEL, first_line); - dd.SaveText(FILENAME_CMDLINE, "not_applicable"); - dd.SaveText(FILENAME_BACKTRACE, second_line); + dd_savetxt(dd, FILENAME_ANALYZER, "Kerneloops"); + dd_savetxt(dd, FILENAME_EXECUTABLE, "kernel"); + dd_savetxt(dd, FILENAME_KERNEL, first_line); + dd_savetxt(dd, FILENAME_CMDLINE, "not_applicable"); + dd_savetxt(dd, FILENAME_BACKTRACE, second_line); /* Optional, makes generated bz more informative */ strchrnul(second_line, '\n')[0] = '\0'; - dd.SaveText(FILENAME_REASON, second_line); - dd.Close(); + dd_savetxt(dd, FILENAME_REASON, second_line); + dd_close(dd); } else errors++; diff --git a/lib/plugins/Python.cpp b/lib/plugins/Python.cpp index 7b6e761a..d634e0c5 100644 --- a/lib/plugins/Python.cpp +++ b/lib/plugins/Python.cpp @@ -26,19 +26,18 @@ using namespace std; string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) { - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - string bt; - dd.LoadText(FILENAME_BACKTRACE, bt); - dd.Close(); + char *bt = dd_loadtxt(dd, FILENAME_BACKTRACE); + dd_close(dd); - const char *bt_str = bt.c_str(); - const char *bt_end = strchrnul(bt_str, '\n'); + const char *bt_end = strchrnul(bt, '\n'); char hash_str[MD5_RESULT_LEN*2 + 1]; unsigned char hash2[MD5_RESULT_LEN]; @@ -49,7 +48,8 @@ string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) //md5_hash(bt_str, bt_end - bt_str, &md5ctx); // For now using compat version: { - char *copy = xstrndup(bt_str, bt_end - bt_str); + char *copy = xstrndup(bt, bt_end - bt); + free(bt); char *s = copy; char *d = copy; unsigned colon_cnt = 0; diff --git a/lib/plugins/RunApp.cpp b/lib/plugins/RunApp.cpp index 632c26f1..f5833565 100644 --- a/lib/plugins/RunApp.cpp +++ b/lib/plugins/RunApp.cpp @@ -58,15 +58,16 @@ void CActionRunApp::Run(const char *pActionDir, const char *pArgs, int force) if (args.size() > FILENAME) { - CDebugDump dd; - if (!dd.Open(pActionDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pActionDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pActionDir); return; } - dd.SaveBinary(args[FILENAME].c_str(), cmd_out, cmd_out_size); - dd.Close(); + dd_savebin(dd, args[FILENAME].c_str(), cmd_out, cmd_out_size); + dd_close(dd); } free(cmd_out); diff --git a/lib/plugins/SOSreport.cpp b/lib/plugins/SOSreport.cpp index 4c9358da..5180266f 100644 --- a/lib/plugins/SOSreport.cpp +++ b/lib/plugins/SOSreport.cpp @@ -51,20 +51,21 @@ void CActionSOSreport::Run(const char *pActionDir, const char *pArgs, int force) { if (!force) { - CDebugDump dd; - if (!dd.Open(pActionDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pActionDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pActionDir); return; } - bool bt_exists = dd.Exist("sosreport.tar.bz2") || dd.Exist("sosreport.tar.xz"); + bool bt_exists = dd_exist(dd, "sosreport.tar.bz2") || dd_exist(dd, "sosreport.tar.xz"); if (bt_exists) { VERB3 log("%s already exists, not regenerating", "sosreport.tar.bz2"); return; } - dd.Close(); + dd_close(dd); } static const char command_default[] = diff --git a/lib/utils/DebugDump.cpp b/lib/utils/DebugDump.cpp index 6858fe36..8987b432 100644 --- a/lib/utils/DebugDump.cpp +++ b/lib/utils/DebugDump.cpp @@ -21,8 +21,8 @@ #include <sys/utsname.h> #include "abrtlib.h" #include "debug_dump.h" -#include "abrt_exception.h" #include "comm_layer_inner.h" +#include "strbuf.h" static bool isdigit_str(const char *str) { @@ -34,12 +34,12 @@ static bool isdigit_str(const char *str) return true; } -static std::string RemoveBackSlashes(const char *pDir) +static char* RemoveBackSlashes(const char *pDir) { unsigned len = strlen(pDir); while (len != 0 && pDir[len-1] == '/') len--; - return std::string(pDir, len); + return xstrndup(pDir, len); } static bool ExistFileDir(const char *pPath) @@ -55,64 +55,63 @@ static bool ExistFileDir(const char *pPath) return false; } -static bool LoadTextFile(const char *pPath, std::string& pData); +static char *LoadTextFile(const char *path); +static void dd_lock(dump_dir_t *dd); +static void dd_unlock(dump_dir_t *dd); -CDebugDump::CDebugDump() : - m_sDebugDumpDir(""), - m_pGetNextFileDir(NULL), - m_bOpened(false), - m_bLocked(false), - m_uid(0), - m_gid(0) -{} +dump_dir_t* dd_init(void) +{ + return (dump_dir_t*)xzalloc(sizeof(dump_dir_t)); +} -CDebugDump::~CDebugDump() +void dd_close(dump_dir_t *dd) { - /* Paranoia. In C++, destructor will abort() if it was called while unwinding - * the stack and it throws an exception. - */ - try - { - Close(); - m_sDebugDumpDir.clear(); - } - catch (...) + if (!dd) + return; + + dd_unlock(dd); + if (dd->next_dir) { - error_msg_and_die("Internal error"); + closedir(dd->next_dir); + free(dd->next_dir); } + + free(dd->dd_dir); + free(dd); } -bool CDebugDump::Open(const char *pDir) +int dd_opendir(dump_dir_t *dd, const char *dir) { - if (m_bOpened) + if (dd->opened) error_msg_and_die("CDebugDump is already opened"); - m_sDebugDumpDir = RemoveBackSlashes(pDir); - if (!ExistFileDir(m_sDebugDumpDir.c_str())) + dd->dd_dir = RemoveBackSlashes(dir); + if (!dd->dd_dir || !ExistFileDir(dd->dd_dir)) { - error_msg("'%s' does not exist", m_sDebugDumpDir.c_str()); - return false; + error_msg("'%s' does not exist", dd->dd_dir); + return 0; } - Lock(); - m_bOpened = true; + + dd_lock(dd); + dd->opened = 1; + /* In case caller would want to create more files, he'll need uid:gid */ - m_uid = 0; - m_gid = 0; struct stat stat_buf; - if (stat(m_sDebugDumpDir.c_str(), &stat_buf) == 0) + if (stat(dd->dd_dir, &stat_buf) == 0) { - m_uid = stat_buf.st_uid; - m_gid = stat_buf.st_gid; + dd->uid = stat_buf.st_uid; + dd->gid = stat_buf.st_gid; } - return true; + + return 1; } -bool CDebugDump::Exist(const char* pPath) +int dd_exist(dump_dir_t *dd, const char *path) { - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pPath); - bool r = ExistFileDir(full_path); + char *full_path = concat_path_file(dd->dd_dir, path); + int ret = ExistFileDir(full_path); free(full_path); - return r; + return ret; } static bool GetAndSetLock(const char* pLockFile, const char* pPID) @@ -143,7 +142,9 @@ static bool GetAndSetLock(const char* pLockFile, const char* pPID) } if (isdigit_str(pid_buf)) { - if (access(ssprintf("/proc/%s", pid_buf).c_str(), F_OK) == 0) + char pid_str[sizeof("/proc/") + strlen(pid_buf)]; + sprintf(pid_str, "/proc/%s", pid_buf); + if (access(pid_str, F_OK) == 0) { log("Lock file '%s' is locked by process %s", pLockFile, pid_buf); return false; @@ -221,28 +222,30 @@ static bool GetAndSetLock(const char* pLockFile, const char* pPID) #endif } -void CDebugDump::Lock() +static void dd_lock(dump_dir_t *dd) { - if (m_bLocked) - error_msg_and_die("Locking bug on '%s'", m_sDebugDumpDir.c_str()); + if (dd->locked) + error_msg_and_die("Locking bug on '%s'", dd->dd_dir); + + char lock_buf[strlen(dd->dd_dir) + sizeof(".lock")]; + sprintf(lock_buf, "%s.lock", dd->dd_dir); - std::string lockFile = m_sDebugDumpDir + ".lock"; char pid_buf[sizeof(long)*3 + 2]; sprintf(pid_buf, "%lu", (long)getpid()); - while ((m_bLocked = GetAndSetLock(lockFile.c_str(), pid_buf)) != true) + while ((dd->locked = GetAndSetLock(lock_buf, pid_buf)) != true) { sleep(1); /* was 0.5 seconds */ } } -void CDebugDump::UnLock() +static void dd_unlock(dump_dir_t *dd) { - if (m_bLocked) + if (dd->locked) { - m_bLocked = false; - std::string lockFile = m_sDebugDumpDir + ".lock"; - xunlink(lockFile.c_str()); - VERB1 log("UnLocked '%s'", lockFile.c_str()); + char lock_buf[strlen(dd->dd_dir) + sizeof(".lock")]; + sprintf(lock_buf, "%s.lock", dd->dd_dir); + xunlink(lock_buf); + VERB1 log("Unlocked '%s'", lock_buf); } } @@ -265,65 +268,67 @@ void CDebugDump::UnLock() * Currently, we set dir's gid to passwd(uid)->pw_gid parameter, and we set uid to * abrt's user id. We do not allow write access to group. */ -bool CDebugDump::Create(const char *pDir, uid_t uid) +int dd_create(dump_dir_t *dd, const char *dir, uid_t uid) { - if (m_bOpened) + if (dd->opened) error_msg_and_die("DebugDump is already opened"); - m_sDebugDumpDir = RemoveBackSlashes(pDir); - if (ExistFileDir(m_sDebugDumpDir.c_str())) + dd->dd_dir = RemoveBackSlashes(dir); + if (ExistFileDir(dd->dd_dir)) { - error_msg("'%s' already exists", m_sDebugDumpDir.c_str()); - return false; + error_msg("'%s' already exists", dd->dd_dir); + return 0; } - Lock(); - m_bOpened = true; + dd_lock(dd); + dd->opened = 1; /* Was creating it with mode 0700 and user as the owner, but this allows * the user to replace any file in the directory, changing security-sensitive data * (e.g. "uid", "analyzer", "executable") */ - if (mkdir(m_sDebugDumpDir.c_str(), 0750) == -1) + if (mkdir(dd->dd_dir, 0750) == -1) { - UnLock(); - m_bOpened = false; - error_msg("Can't create dir '%s'", pDir); - return false; + dd_unlock(dd); + dd->opened = 0; + error_msg("Can't create dir '%s'", dir); + return 0; } /* mkdir's mode (above) can be affected by umask, fix it */ - if (chmod(m_sDebugDumpDir.c_str(), 0750) == -1) + if (chmod(dd->dd_dir, 0750) == -1) { - UnLock(); - m_bOpened = false; - error_msg("Can't change mode of '%s'", pDir); + dd_unlock(dd); + dd->opened = false; + error_msg("Can't change mode of '%s'", dir); return false; } /* Get ABRT's user id */ - m_uid = 0; + dd->uid = 0; struct passwd *pw = getpwnam("abrt"); if (pw) - m_uid = pw->pw_uid; + dd->uid = pw->pw_uid; else error_msg("User 'abrt' does not exist, using uid 0"); /* Get crashed application's group id */ - m_gid = 0; + dd->gid = 0; pw = getpwuid(uid); if (pw) - m_gid = pw->pw_gid; + dd->gid = pw->pw_gid; else - error_msg("User %lu does not exist, using gid 0", (long)uid); + error_msg("User %lu does not exist, using gid 0", (long)uid); - if (chown(m_sDebugDumpDir.c_str(), m_uid, m_gid) == -1) + if (chown(dd->dd_dir, dd->uid, dd->gid) == -1) { - perror_msg("can't change '%s' ownership to %lu:%lu", m_sDebugDumpDir.c_str(), - (long)m_uid, (long)m_gid); + perror_msg("can't change '%s' ownership to %lu:%lu", dd->dd_dir, + (long)dd->uid, (long)dd->gid); } - SaveText(CD_UID, to_string(uid).c_str()); + char uid_str[sizeof(long) * 3 + 2]; + sprintf(uid_str, "%lu", (long)uid); + dd_savetxt(dd, CD_UID, uid_str); { struct utsname buf; @@ -331,20 +336,20 @@ bool CDebugDump::Create(const char *pDir, uid_t uid) { perror_msg_and_die("uname"); } - SaveText(FILENAME_KERNEL, buf.release); - SaveText(FILENAME_ARCHITECTURE, buf.machine); - std::string release; - LoadTextFile("/etc/redhat-release", release); - const char *release_ptr = release.c_str(); - unsigned len_1st_str = strchrnul(release_ptr, '\n') - release_ptr; - release.erase(len_1st_str); /* usually simply removes trailing '\n' */ - SaveText(FILENAME_RELEASE, release.c_str()); + dd_savetxt(dd, FILENAME_KERNEL, buf.release); + dd_savetxt(dd, FILENAME_ARCHITECTURE, buf.machine); + char *release = LoadTextFile("/etc/redhat-release"); + strchrnul(release, '\n')[0] = '\0'; + dd_savetxt(dd, FILENAME_RELEASE, release); + free(release); } time_t t = time(NULL); - SaveText(FILENAME_TIME, to_string(t).c_str()); + char t_str[sizeof(time_t) * 3 + 2]; + sprintf(t_str, "%lu", (time_t)t); + dd_savetxt(dd, FILENAME_TIME, t_str); - return true; + return 1; } static bool DeleteFileDir(const char *pDir) @@ -352,15 +357,15 @@ static bool DeleteFileDir(const char *pDir) if (!ExistFileDir(pDir)) return true; - DIR *dir = opendir(pDir); - if (!dir) + DIR *d = opendir(pDir); + if (!d) { error_msg("Can't open dir '%s'", pDir); return false; } struct dirent *dent; - while ((dent = readdir(dir)) != NULL) + while ((dent = readdir(d)) != NULL) { if (dot_or_dotdot(dent->d_name)) continue; @@ -369,7 +374,7 @@ static bool DeleteFileDir(const char *pDir) { if (errno != EISDIR) { - closedir(dir); + closedir(d); error_msg("Can't remove dir '%s'", full_path); free(full_path); return false; @@ -378,7 +383,7 @@ static bool DeleteFileDir(const char *pDir) } free(full_path); } - closedir(dir); + closedir(d); if (rmdir(pDir) == -1) { error_msg("Can't remove dir %s", pDir); @@ -388,52 +393,40 @@ static bool DeleteFileDir(const char *pDir) return true; } -void CDebugDump::Delete() +void dd_delete(dump_dir_t *dd) { - if (!ExistFileDir(m_sDebugDumpDir.c_str())) + if (!ExistFileDir(dd->dd_dir)) { return; } - DeleteFileDir(m_sDebugDumpDir.c_str()); -} -void CDebugDump::Close() -{ - UnLock(); - if (m_pGetNextFileDir != NULL) - { - closedir(m_pGetNextFileDir); - m_pGetNextFileDir = NULL; - } - m_bOpened = false; + DeleteFileDir(dd->dd_dir); } -static bool LoadTextFile(const char *pPath, std::string& pData) +static char *LoadTextFile(const char *pPath) { FILE *fp = fopen(pPath, "r"); if (!fp) { - error_msg("Can't open file '%s'", pPath); - return false; + perror_msg("Can't open file '%s'", pPath); + return xstrdup(""); } - pData = ""; + + struct strbuf *buf_content = strbuf_new(); int ch; while ((ch = fgetc(fp)) != EOF) { if (ch == '\0') - { - pData += ' '; - } + strbuf_append_char(buf_content, ' '); else if (isspace(ch) || (isascii(ch) && !iscntrl(ch))) - { - pData += ch; - } + strbuf_append_char(buf_content, ch); } fclose(fp); - return true; + + return strbuf_free_nobuf(buf_content); } -static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, uid_t uid, gid_t gid) +static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned size, uid_t uid, gid_t gid) { /* "Why 0640?!" See ::Create() for security analysis */ unlink(pPath); @@ -447,9 +440,9 @@ static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, { perror_msg("can't change '%s' ownership to %lu:%lu", pPath, (long)uid, (long)gid); } - unsigned r = full_write(fd, pData, pSize); + unsigned r = full_write(fd, pData, size); close(fd); - if (r != pSize) + if (r != size) { error_msg("Can't save file '%s'", pPath); return false; @@ -458,85 +451,86 @@ static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, return true; } -void CDebugDump::LoadText(const char* pName, std::string& pData) +char* dd_loadtxt(const dump_dir_t *dd, const char *name) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - LoadTextFile(full_path, pData); + char *full_path = concat_path_file(dd->dd_dir, name); + char *ret = LoadTextFile(full_path); free(full_path); + + return ret; } -void CDebugDump::SaveText(const char* pName, const char* pData) +void dd_savetxt(dump_dir_t *dd, const char *name, const char *data) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - SaveBinaryFile(full_path, pData, strlen(pData), m_uid, m_gid); + char *full_path = concat_path_file(dd->dd_dir, name); + SaveBinaryFile(full_path, data, strlen(data), dd->uid, dd->gid); free(full_path); } -void CDebugDump::SaveBinary(const char* pName, const char* pData, unsigned pSize) +void dd_savebin(dump_dir_t* dd, const char* name, const char* data, unsigned size) { - if (!m_bOpened) + if (dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - SaveBinaryFile(full_path, pData, pSize, m_uid, m_gid); + + char *full_path = concat_path_file(dd->dd_dir, name); + SaveBinaryFile(full_path, data, size, dd->uid, dd->gid); free(full_path); } -bool CDebugDump::InitGetNextFile() +int dd_init_next_file(dump_dir_t *dd) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - if (m_pGetNextFileDir != NULL) - { - closedir(m_pGetNextFileDir); - } - m_pGetNextFileDir = opendir(m_sDebugDumpDir.c_str()); - if (m_pGetNextFileDir == NULL) + if (dd->next_dir) + closedir(dd->next_dir); + + dd->next_dir = opendir(dd->dd_dir); + if (!dd->next_dir) { - error_msg("Can't open dir '%s'", m_sDebugDumpDir.c_str()); - return false; + error_msg("Can't open dir '%s'", dd->dd_dir); + return 0; } - return true; + return 1; } -bool CDebugDump::GetNextFile(std::string *short_name, std::string *full_name) +int dd_get_next_file(dump_dir_t *dd, char **short_name, char **full_name) { - if (m_pGetNextFileDir == NULL) - return false; + if (dd->next_dir == NULL) + return 0; struct dirent *dent; - while ((dent = readdir(m_pGetNextFileDir)) != NULL) + while ((dent = readdir(dd->next_dir)) != NULL) { - if (is_regular_file(dent, m_sDebugDumpDir.c_str())) + if (is_regular_file(dent, dd->dd_dir)) { if (short_name) - *short_name = dent->d_name; + *short_name = xstrdup(dent->d_name); if (full_name) - *full_name = concat_path_file(m_sDebugDumpDir.c_str(), dent->d_name); - return true; + *full_name = concat_path_file(dd->dd_dir, dent->d_name); + return 1; } } - closedir(m_pGetNextFileDir); - m_pGetNextFileDir = NULL; - return false; + + closedir(dd->next_dir); + dd->next_dir = NULL; + return 0; } /* Utility function */ -void delete_debug_dump_dir(const char *pDebugDumpDir) +void delete_debug_dump_dir(const char *dd_dir) { - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) - { - dd.Delete(); - dd.Close(); - } + dump_dir_t *dd = dd_init(); + if (dd_opendir(dd, dd_dir)) + dd_delete(dd); else - VERB1 log("Unable to open debug dump '%s'", pDebugDumpDir); + VERB1 log("Unable to open debug dump '%s'", dd_dir); + dd_close(dd); } diff --git a/src/daemon/MiddleWare.cpp b/src/daemon/MiddleWare.cpp index 9872a412..e8c7d856 100644 --- a/src/daemon/MiddleWare.cpp +++ b/src/daemon/MiddleWare.cpp @@ -130,48 +130,52 @@ static char* is_text_file(const char *name, ssize_t *sz) return NULL; /* it's binary */ } -static void load_crash_data_from_debug_dump(CDebugDump& dd, map_crash_data_t& data) +static void load_crash_data_from_debug_dump(dump_dir_t *dd, map_crash_data_t& data) { - VERB3 log("load_crash_data_from_debug_dump: directory %s", dd.Directory()); - std::string short_name; - std::string full_name; + char *short_name; + char *full_name; - dd.InitGetNextFile(); - while (dd.GetNextFile(&short_name, &full_name)) + dd_init_next_file(dd); + while (dd_get_next_file(dd, &short_name, &full_name)) { - VERB3 log("load_crash_data_from_debug_dump: file '%s', '%s'", short_name.c_str(), full_name.c_str()); ssize_t sz = 4*1024; char *text = NULL; - bool editable = is_editable_file(short_name.c_str()); + bool editable = is_editable_file(short_name); if (!editable) { - text = is_text_file(full_name.c_str(), &sz); + text = is_text_file(full_name, &sz); if (!text) { add_to_crash_data_ext(data, - short_name.c_str(), + short_name, CD_BIN, CD_ISNOTEDITABLE, - full_name.c_str() + full_name ); + + free(short_name); + free(full_name); continue; } } - std::string content; + char *content; if (sz < 4*1024) /* is_text_file did read entire file */ - content.assign(text, sz); + content = xstrndup(text, sz); //TODO: can avoid this copying if is_text_file() adds NUL else /* no, need to read it all */ - dd.LoadText(short_name.c_str(), content); + content = dd_loadtxt(dd, short_name); free(text); add_to_crash_data_ext(data, - short_name.c_str(), + short_name, CD_TXT, editable ? CD_ISEDITABLE : CD_ISNOTEDITABLE, - content.c_str() + content ); + free(short_name); + free(full_name); + free(content); } } @@ -185,25 +189,28 @@ static bool DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_data_t& { VERB3 log(" DebugDumpToCrashReport('%s')", pDebugDumpDir); - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (dd_opendir(dd, pDebugDumpDir)) { const char *const *v = must_have_files; while (*v) { - if (!dd.Exist(*v)) + if (!dd_exist(dd, *v)) { + dd_close(dd); throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): important file '%s' is missing", *v); } + v++; } load_crash_data_from_debug_dump(dd, pCrashData); - dd.Close(); + dd_close(dd); return true; } + dd_close(dd); return false; } @@ -293,14 +300,15 @@ mw_result_t CreateCrashReport(const char *crash_id, mw_result_t r = MW_OK; try { - CDebugDump dd; - if (dd.Open(row.m_sDebugDumpDir.c_str())) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, row.m_sDebugDumpDir.c_str())) { - load_crash_data_from_debug_dump(dd, pCrashData); - dd.Close(); - } - else + dd_close(dd); return MW_ERROR; + } + + load_crash_data_from_debug_dump(dd, pCrashData); + dd_close(dd); std::string analyzer = get_crash_data_item_content(pCrashData, FILENAME_ANALYZER); const char* package = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_PACKAGE); @@ -446,27 +454,26 @@ report_status_t Report(const map_crash_data_t& client_report, const char *backtrace = get_crash_data_item_content_or_NULL(client_report, FILENAME_BACKTRACE); if (comment || reproduce || backtrace) { - CDebugDump dd; - if (dd.Open(pDumpDir.c_str())) + dump_dir_t *dd = dd_init(); + if (dd_opendir(dd, pDumpDir.c_str())) { if (comment) { - dd.SaveText(FILENAME_COMMENT, comment); + dd_savetxt(dd, FILENAME_COMMENT, comment); add_to_crash_data_ext(stored_report, FILENAME_COMMENT, CD_TXT, CD_ISEDITABLE, comment); } if (reproduce) { - dd.SaveText(FILENAME_REPRODUCE, reproduce); + dd_savetxt(dd, FILENAME_REPRODUCE, reproduce); add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce); } if (backtrace) { - dd.SaveText(FILENAME_BACKTRACE, backtrace); + dd_savetxt(dd, FILENAME_BACKTRACE, backtrace); add_to_crash_data_ext(stored_report, FILENAME_BACKTRACE, CD_TXT, CD_ISEDITABLE, backtrace); } - - dd.Close(); } + dd_close(dd); } /* Remove BIN filenames from stored_report if they are not present in client's data */ @@ -721,18 +728,19 @@ static mw_result_t SavePackageDescriptionToDebugDump( { VERB2 log("Crash in unpackaged executable '%s', proceeding without packaging information", pExecutable); - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { - dd.SaveText(FILENAME_PACKAGE, ""); - dd.SaveText(FILENAME_COMPONENT, ""); - dd.SaveText(FILENAME_DESCRIPTION, "Crashed executable does not belong to any installed package"); - - dd.Close(); - return MW_OK; - } - else + dd_close(dd); return MW_ERROR; + } + + dd_savetxt(dd, FILENAME_PACKAGE, ""); + dd_savetxt(dd, FILENAME_COMPONENT, ""); + dd_savetxt(dd, FILENAME_DESCRIPTION, "Crashed executable does not belong to any installed package"); + + dd_close(dd); + return MW_OK; } else { @@ -845,32 +853,34 @@ static mw_result_t SavePackageDescriptionToDebugDump( } } - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (dd_opendir(dd, pDebugDumpDir)) { if (rpm_pkg) { - dd.SaveText(FILENAME_PACKAGE, rpm_pkg); + dd_savetxt(dd, FILENAME_PACKAGE, rpm_pkg); free(rpm_pkg); } if (dsc) { - dd.SaveText(FILENAME_DESCRIPTION, dsc); + dd_savetxt(dd, FILENAME_DESCRIPTION, dsc); free(dsc); } if (component) { - dd.SaveText(FILENAME_COMPONENT, component); + dd_savetxt(dd, FILENAME_COMPONENT, component); free(component); } if (!remote) - dd.SaveText(FILENAME_HOSTNAME, host); + dd_savetxt(dd, FILENAME_HOSTNAME, host); + dd_close(dd); return MW_OK; } + dd_close(dd); return MW_ERROR; } @@ -1027,66 +1037,85 @@ static mw_result_t SaveDebugDumpToDatabase(const char *crash_id, mw_result_t SaveDebugDump(const char *pDebugDumpDir, map_crash_data_t& pCrashData) { - std::string UID; - std::string time; - std::string analyzer; - std::string executable; - std::string cmdline; - bool remote = false; + mw_result_t res; + int remote = 0; - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { - dd.LoadText(FILENAME_TIME, time); - dd.LoadText(CD_UID, UID); - dd.LoadText(FILENAME_ANALYZER, analyzer); - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_CMDLINE, cmdline); - if (dd.Exist(FILENAME_REMOTE)) - { - std::string remote_str; - dd.LoadText(FILENAME_REMOTE, remote_str); - remote = (remote_str.find('1') != std::string::npos); - } - - dd.Close(); - } - else + dd_close(dd); return MW_ERROR; + } + + char *time = dd_loadtxt(dd, FILENAME_TIME); + char *uid = dd_loadtxt(dd, CD_UID); + char *analyzer = dd_loadtxt(dd, FILENAME_ANALYZER); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *cmdline = dd_loadtxt(dd, FILENAME_CMDLINE); + + char *remote_str = xstrdup(""); + if (dd_exist(dd, FILENAME_REMOTE)) + remote_str = dd_loadtxt(dd, FILENAME_REMOTE); + + dd_close(dd); /* Convert UID string to number uid_num. The UID string can be modified by user or wrongly saved (empty or non-numeric), so xatou() cannot be used here, because it would kill the daemon. */ char *endptr; errno = 0; - unsigned long uid_num = strtoul(UID.c_str(), &endptr, 10); - if (errno || UID.c_str() == endptr || *endptr != '\0' || uid_num > UINT_MAX) + unsigned long uid_num = strtoul(uid, &endptr, 10); + if (errno || uid == endptr || *endptr != '\0' || uid_num > UINT_MAX) { - error_msg("Invalid UID '%s' loaded from %s", UID.c_str(), pDebugDumpDir); - return MW_ERROR; + error_msg("Invalid UID '%s' loaded from %s", uid, pDebugDumpDir); + res = MW_ERROR; + goto error; } if (is_debug_dump_saved(uid_num, pDebugDumpDir)) - return MW_IN_DB; + { + res = MW_IN_DB; + goto error; + } - mw_result_t res = SavePackageDescriptionToDebugDump(executable.c_str(), cmdline.c_str(), remote, pDebugDumpDir); + if (remote_str[0]) + remote = remote_str[0] != '1'; + + res = SavePackageDescriptionToDebugDump(executable, + cmdline, + remote, + pDebugDumpDir + ); if (res != MW_OK) - return res; - - std::string UUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir); - std::string crash_id = ssprintf("%s:%s", UID.c_str(), UUID.c_str()); - /* Loads pCrashData (from the *first debugdump dir* if this one is a dup) - * Returns: - * MW_REPORTED: "the crash is flagged as reported in DB" (which also means it's a dup) - * MW_OCCURRED: "crash count is != 1" (iow: it is > 1 - dup) - * MW_OK: "crash count is 1" (iow: this is a new crash, not a dup) - * else: an error code - */ - return SaveDebugDumpToDatabase(crash_id.c_str(), - analyzer_has_InformAllUsers(analyzer.c_str()), - time.c_str(), - pDebugDumpDir, - pCrashData); + goto error; + + { + std::string UUID = GetLocalUUID((analyzer) ? analyzer : "", pDebugDumpDir); + std::string crash_id = ssprintf("%s:%s", uid, UUID.c_str()); + /* Loads pCrashData (from the *first debugdump dir* if this one is a dup) + * Returns: + * MW_REPORTED: "the crash is flagged as reported in DB" (which also means it's a dup) + * MW_OCCURRED: "crash count is != 1" (iow: it is > 1 - dup) + * MW_OK: "crash count is 1" (iow: this is a new crash, not a dup) + * else: an error code + */ + + res = SaveDebugDumpToDatabase(crash_id.c_str(), + analyzer_has_InformAllUsers(analyzer), + time, + pDebugDumpDir, + pCrashData); + } + +error: + free(remote_str); + free(time); + free(executable); + free(cmdline); + free(uid); + free(analyzer); + + return res; } mw_result_t FillCrashInfo(const char *crash_id, @@ -1102,14 +1131,15 @@ mw_result_t FillCrashInfo(const char *crash_id, std::string description; std::string analyzer; - CDebugDump dd; - if (dd.Open(row.m_sDebugDumpDir.c_str())) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, row.m_sDebugDumpDir.c_str())) { - load_crash_data_from_debug_dump(dd, pCrashData); - dd.Close(); - } - else + dd_close(dd); return MW_ERROR; + } + + load_crash_data_from_debug_dump(dd, pCrashData); + dd_close(dd); add_to_crash_data(pCrashData, CD_UID , row.m_sUID.c_str() ); add_to_crash_data(pCrashData, CD_UUID , row.m_sUUID.c_str() ); diff --git a/src/daemon/dumpsocket.cpp b/src/daemon/dumpsocket.cpp index f95197f6..999df00f 100644 --- a/src/daemon/dumpsocket.cpp +++ b/src/daemon/dumpsocket.cpp @@ -170,33 +170,33 @@ static void create_debug_dump(struct client *client) client->basename, (long)time(NULL), client->pid); - /* No need to check the path length, as all variables used are limited, and dd.Create() + /* No need to check the path length, as all variables used are limited, and dd_create() fails if the path is too long. */ - CDebugDump dd; - if (!dd.Create(path, client->uid)) + dump_dir_t *dd = dd_init();; + if (!dd_create(dd, path, client->uid)) { - dd.Delete(); - dd.Close(); + dd_delete(dd); + dd_close(dd); error_msg_and_die("dumpsocket: Error while creating crash dump %s", path); } - dd.SaveText(FILENAME_ANALYZER, client->analyzer); - dd.SaveText(FILENAME_EXECUTABLE, client->executable); - dd.SaveText(FILENAME_BACKTRACE, client->backtrace); - dd.SaveText(FILENAME_REASON, client->reason); + dd_savetxt(dd, FILENAME_ANALYZER, client->analyzer); + dd_savetxt(dd, FILENAME_EXECUTABLE, client->executable); + dd_savetxt(dd, FILENAME_BACKTRACE, client->backtrace); + dd_savetxt(dd, FILENAME_REASON, client->reason); /* Obtain and save the command line. */ char *cmdline = get_cmdline(client->pid); // never NULL - dd.SaveText(FILENAME_CMDLINE, cmdline); + dd_savetxt(dd, FILENAME_CMDLINE, cmdline); free(cmdline); /* Store id of the user whose application crashed. */ char uid_str[sizeof(long) * 3 + 2]; sprintf(uid_str, "%lu", (long)client->uid); - dd.SaveText(CD_UID, uid_str); + dd_savetxt(dd, CD_UID, uid_str); - dd.Close(); + dd_close(dd); /* Move the completely created debug dump to final directory. */ diff --git a/src/hooks/abrt-hook-ccpp.cpp b/src/hooks/abrt-hook-ccpp.cpp index 1e469890..4862c6c1 100644 --- a/src/hooks/abrt-hook-ccpp.cpp +++ b/src/hooks/abrt-hook-ccpp.cpp @@ -415,15 +415,15 @@ int main(int argc, char** argv) if (path_len >= (sizeof(path) - sizeof("/"FILENAME_COREDUMP))) return 1; - CDebugDump dd; - if (dd.Create(path, uid)) + dump_dir_t *dd = dd_init(); + if (dd_create(dd, path, uid)) { char *cmdline = get_cmdline(pid); /* never NULL */ char *reason = xasprintf("Process %s was killed by signal %s (SIG%s)", executable, signal_str, signame ? signame : signal_str); - dd.SaveText(FILENAME_ANALYZER, "CCpp"); - dd.SaveText(FILENAME_EXECUTABLE, executable); - dd.SaveText(FILENAME_CMDLINE, cmdline); - dd.SaveText(FILENAME_REASON, reason); + dd_savetxt(dd, FILENAME_ANALYZER, "CCpp"); + dd_savetxt(dd, FILENAME_EXECUTABLE, executable); + dd_savetxt(dd, FILENAME_CMDLINE, cmdline); + dd_savetxt(dd, FILENAME_REASON, reason); free(cmdline); free(reason); @@ -451,8 +451,8 @@ int main(int argc, char** argv) if (abrt_core_fd < 0) { int sv_errno = errno; - dd.Delete(); - dd.Close(); + dd_delete(dd); + dd_close(dd); if (user_core_fd >= 0) { xchdir(user_pwd); @@ -480,8 +480,8 @@ int main(int argc, char** argv) if (core_size < 0 || fsync(abrt_core_fd) != 0) { unlink(path); - dd.Delete(); - dd.Close(); + dd_delete(dd); + dd_close(dd); if (user_core_fd >= 0) { xchdir(user_pwd); @@ -505,7 +505,7 @@ int main(int argc, char** argv) * will wait for us), and we won't be able to delete their dumps. * Classic deadlock. */ - dd.Close(); + dd_close(dd); path[path_len] = '\0'; /* path now contains only directory name */ char *newpath = xstrndup(path, path_len - (sizeof(".new")-1)); if (rename(path, newpath) == 0) |
