summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/analyzer.h7
-rw-r--r--inc/crash_types.h4
-rw-r--r--lib/plugins/CCpp.cpp294
-rw-r--r--lib/plugins/CCpp.h1
-rw-r--r--lib/plugins/Kerneloops.h1
-rw-r--r--lib/plugins/Python.h1
-rw-r--r--src/daemon/MiddleWare.cpp139
-rw-r--r--src/daemon/abrt_event.conf12
8 files changed, 18 insertions, 441 deletions
diff --git a/inc/analyzer.h b/inc/analyzer.h
index 122b222e..3f2c6952 100644
--- a/inc/analyzer.h
+++ b/inc/analyzer.h
@@ -36,13 +36,6 @@ class CAnalyzer : public CPlugin
* @return A global UUID.
*/
virtual std::string GetGlobalUUID(const char *pDebugDumpDir) = 0;
- /**
- * A method, which takes care of getting all additional data needed
- * for computing UUIDs and creating a report. This report could be send
- * somewhere afterwards.
- * @param pDebugDumpPath A debugdump dir containing all necessary data.
- */
- virtual void CreateReport(const char *pDebugDumpDir, int force) = 0;
};
#endif /*ANALYZER_H_*/
diff --git a/inc/crash_types.h b/inc/crash_types.h
index 6308db89..96d05d38 100644
--- a/inc/crash_types.h
+++ b/inc/crash_types.h
@@ -33,9 +33,7 @@
#define FILENAME_COREDUMP "coredump"
#define FILENAME_BACKTRACE "backtrace"
#define FILENAME_MEMORYMAP "memorymap"
-// Used by CCpp analyzer to cache GetGlobalUUID() calls.
-// FIXME! make ALL analyzers to save it as a file!
-// Now, Python and kerneloops do not!
+// Used to cache GetGlobalUUID() calls
#define FILENAME_DUPHASH "global_uuid" /* name is compat, to be renamed to "duphash" */
// Name of the function where the application crashed.
// Optional.
diff --git a/lib/plugins/CCpp.cpp b/lib/plugins/CCpp.cpp
index 7415891f..ddc17206 100644
--- a/lib/plugins/CCpp.cpp
+++ b/lib/plugins/CCpp.cpp
@@ -74,197 +74,6 @@ static void create_hash(char hash_str[SHA1_RESULT_LEN*2 + 1], const char *pInput
//log("hash2:%s str:'%s'", hash_str, pInput);
}
-static void gen_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs, unsigned timeout_sec)
-{
- update_client(_("Generating backtrace"));
-
- pid_t pid = fork();
- if (pid < 0)
- {
- perror_msg("fork");
- return;
- }
- if (pid == 0) /* child */
- {
- char *argv[8]; /* abrt-action-generate-backtrace [-s] -tSEC -d DIR -i DIR1:DIR2 NULL */
- char **pp = argv;
- *pp++ = (char*)"abrt-action-generate-backtrace";
- if (logmode & LOGMODE_SYSLOG)
- *pp++ = (char*)"-s";
- *pp++ = xasprintf("-t%u", timeout_sec);
- *pp++ = (char*)"-d";
- *pp++ = (char*)pDebugDumpDir;
- *pp++ = (char*)"-i";
- *pp++ = (char*)pDebugInfoDirs;
- *pp = NULL;
-
- execvp(argv[0], argv);
- perror_msg_and_die("Can't execute '%s'", argv[0]);
- }
- /* parent */
- waitpid(pid, NULL, 0);
-}
-
-/* Needs gdb feature from here: https://bugzilla.redhat.com/show_bug.cgi?id=528668
- * It is slated to be in F12/RHEL6.
- *
- * returned value must be freed
- */
-static char *install_debug_infos(const char *pDebugDumpDir, const char *debuginfo_dirs)
-{
- update_client(_("Starting the debuginfo installation"));
-
- int pipeout[2]; //TODO: can we use ExecVP?
- xpipe(pipeout);
-
- fflush(NULL);
- pid_t child = fork();
- if (child < 0)
- {
- /*close(pipeout[0]); - why bother */
- /*close(pipeout[1]); */
- perror_msg_and_die("fork");
- }
- if (child == 0)
- {
- close(pipeout[0]);
- xmove_fd(pipeout[1], STDOUT_FILENO);
- xmove_fd(xopen("/dev/null", O_RDONLY), STDIN_FILENO);
-
- char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir);
- /* SELinux guys are not happy with /tmp, using /var/run/abrt */
- char *tempdir = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%lu-%lu", (long)getpid(), (long)time(NULL));
- /* log() goes to stderr/syslog, it's ok to use it here */
- VERB1 log("Executing: %s %s %s %s", "abrt-action-install-debuginfo", coredump, tempdir, debuginfo_dirs);
- /* We want parent to see errors in the same stream */
- xdup2(STDOUT_FILENO, STDERR_FILENO);
- execlp("abrt-action-install-debuginfo", "abrt-action-install-debuginfo", coredump, tempdir, debuginfo_dirs, NULL);
- perror_msg("Can't execute '%s'", "abrt-action-install-debuginfo");
- /* Serious error (1 means "some debuginfos not found") */
- exit(2);
- }
-
- close(pipeout[1]);
-
- FILE *pipeout_fp = fdopen(pipeout[0], "r");
- if (pipeout_fp == NULL) /* never happens */
- {
- close(pipeout[0]);
- waitpid(child, NULL, 0);
- return NULL;
- }
-
- char *buff;
- struct strbuf *buf_build_ids = strbuf_new();
- while ((buff = xmalloc_fgetline(pipeout_fp)) != NULL)
- {
- if (strncmp(buff, "MISSING:", 8) == 0)
- {
- strbuf_append_strf(buf_build_ids, "Debuginfo absent: %s\n", buff + 8);
- free(buff);
- continue;
- }
-
- const char *p = buff;
- while (*p == ' ' || *p == '\t')
- {
- p++;
- }
-
- if (*p)
- {
- VERB1 log("%s", buff);
- update_client("%s", buff);
- }
- free(buff);
- }
- fclose(pipeout_fp);
-
- int status = 0;
- while (waitpid(child, &status, 0) < 0 && errno == EINTR)
- continue;
- if (WIFEXITED(status))
- {
- if (WEXITSTATUS(status) > 1)
- error_msg("%s exited with %u", "abrt-action-install-debuginfo", (int)WEXITSTATUS(status));
- }
- else
- {
- error_msg("%s killed by signal %u", "abrt-action-install-debuginfo", (int)WTERMSIG(status));
- }
-
- return strbuf_free_nobuf(buf_build_ids);
-}
-
-static double get_dir_size(const char *dirname,
- string *worst_file,
- double *maxsz)
-{
- DIR *dp = opendir(dirname);
- if (dp == NULL)
- return 0;
-
- struct dirent *ep;
- struct stat stats;
- double size = 0;
- while ((ep = readdir(dp)) != NULL)
- {
- if (dot_or_dotdot(ep->d_name))
- continue;
- char *dname = concat_path_file(dirname, ep->d_name);
- if (lstat(dname, &stats) != 0)
- {
- free(dname);
- continue;
- }
- if (S_ISDIR(stats.st_mode))
- {
- double sz = get_dir_size(dname, worst_file, maxsz);
- size += sz;
- }
- else if (S_ISREG(stats.st_mode))
- {
- double sz = stats.st_size;
- size += sz;
-
- if (worst_file)
- {
- /* Calculate "weighted" size and age
- * w = sz_kbytes * age_mins */
- sz /= 1024;
- long age = (time(NULL) - stats.st_mtime) / 60;
- if (age > 0)
- sz *= age;
-
- if (sz > *maxsz)
- {
- *maxsz = sz;
- *worst_file = dname;
- }
- }
- }
- free(dname);
- }
- closedir(dp);
- return size;
-}
-
-static void trim_debuginfo_cache(unsigned max_mb)
-{
- while (1)
- {
- string worst_file;
- double maxsz = 0;
- double cache_sz = get_dir_size(DEBUGINFO_CACHE_DIR, &worst_file, &maxsz);
- if (cache_sz / (1024 * 1024) < max_mb)
- break;
- VERB1 log("%s is %.0f bytes (over %u MB), deleting '%s'",
- DEBUGINFO_CACHE_DIR, cache_sz, max_mb, worst_file.c_str());
- if (unlink(worst_file.c_str()) != 0)
- perror_msg("Can't unlink '%s'", worst_file.c_str());
- }
-}
-
string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir)
{
struct dump_dir *dd = dd_opendir(pDebugDumpDir, /*flags:*/ 0);
@@ -402,109 +211,6 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir)
}
}
-static bool DebuginfoCheckPolkit(uid_t uid)
-{
- fflush(NULL);
- int child_pid = fork();
- if (child_pid < 0)
- {
- perror_msg_and_die("fork");
- }
-
- if (child_pid == 0)
- {
- //child
- xsetreuid(uid, uid);
- PolkitResult result = polkit_check_authorization(getpid(),
- "org.fedoraproject.abrt.install-debuginfos");
- exit(result != PolkitYes); //exit 1 (failure) if not allowed
- }
-
- //parent
- int status;
- if (waitpid(child_pid, &status, 0) > 0
- && WIFEXITED(status)
- && WEXITSTATUS(status) == 0
- ) {
- return true; //authorization OK
- }
- log("UID %d is not authorized to install debuginfos", uid);
- return false;
-}
-
-void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force)
-{
- if (!m_bBacktrace)
- {
- return;
- }
-
- struct dump_dir *dd = dd_opendir(pDebugDumpDir, /*flags:*/ 0);
- if (!dd)
- return;
-
- if (!force)
- {
- int bt_exists = dd_exist(dd, FILENAME_BACKTRACE);
- if (bt_exists)
- {
- dd_close(dd);
- return; /* backtrace already exists */
- }
- }
-
- /* Skip remote crashes. */
- if (dd_exist(dd, FILENAME_REMOTE))
- {
- char *remote_str = dd_load_text(dd, FILENAME_REMOTE);
- bool remote = (remote_str[0] != '1');
- free(remote_str);
- if (remote && !m_bBacktraceRemotes)
- {
- dd_close(dd);
- return;
- }
- }
-
- char *uid = dd_load_text(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)))
- {
- if (m_nDebugInfoCacheMB > 0)
- trim_debuginfo_cache(m_nDebugInfoCacheMB);
- build_ids = install_debug_infos(pDebugDumpDir, m_sDebugInfoDirs.c_str());
- }
- else
- VERB1 log(_("Skipping the debuginfo installation"));
- free(uid);
-
- /* Create and store backtrace and its hash. */
- gen_backtrace(pDebugDumpDir, m_sDebugInfoDirs.c_str(), m_nGdbTimeoutSec);
-
- dd = dd_opendir(pDebugDumpDir, /*flags:*/ 0);
- if (!dd)
- {
- free(build_ids);
- return;
- }
-
- /* Add build_ids to backtrace */
- char *backtrace_str = dd_load_text(dd, FILENAME_BACKTRACE);
- char *bt_build_ids = xasprintf("%s%s", backtrace_str, (build_ids) ? build_ids : "");
- dd_save_text(dd, FILENAME_BACKTRACE, bt_build_ids);
- free(build_ids);
- free(bt_build_ids);
- free(backtrace_str);
-
- /* TODO: remove, it's much easier to collect in the coredump helper */
- if (m_bMemoryMap)
- dd_save_text(dd, FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet");
-
- dd_close(dd);
-}
-
/*
this is just a workaround until kernel changes it's behavior
when handling pipes in core_pattern
diff --git a/lib/plugins/CCpp.h b/lib/plugins/CCpp.h
index e8040449..dcd80982 100644
--- a/lib/plugins/CCpp.h
+++ b/lib/plugins/CCpp.h
@@ -42,7 +42,6 @@ class CAnalyzerCCpp : public CAnalyzer
public:
CAnalyzerCCpp();
virtual std::string GetGlobalUUID(const char *pDebugDumpDir);
- virtual void CreateReport(const char *pDebugDumpDir, int force);
virtual void Init();
virtual void DeInit();
virtual void SetSettings(const map_plugin_settings_t& pSettings);
diff --git a/lib/plugins/Kerneloops.h b/lib/plugins/Kerneloops.h
index 10253fe4..af6bef0e 100644
--- a/lib/plugins/Kerneloops.h
+++ b/lib/plugins/Kerneloops.h
@@ -35,7 +35,6 @@ class CAnalyzerKerneloops : public CAnalyzer
{
public:
virtual std::string GetGlobalUUID(const char *pDebugDumpDir);
- virtual void CreateReport(const char *pDebugDumpDir, int force) {}
};
#endif
diff --git a/lib/plugins/Python.h b/lib/plugins/Python.h
index ebb1ec6f..c862ad45 100644
--- a/lib/plugins/Python.h
+++ b/lib/plugins/Python.h
@@ -27,7 +27,6 @@ class CAnalyzerPython : public CAnalyzer
{
public:
virtual std::string GetGlobalUUID(const char *pDebugDumpDir);
- virtual void CreateReport(const char *pDebugDumpDir, int force) {}
virtual void Init();
virtual void DeInit();
};
diff --git a/src/daemon/MiddleWare.cpp b/src/daemon/MiddleWare.cpp
index d51813b2..af12bd21 100644
--- a/src/daemon/MiddleWare.cpp
+++ b/src/daemon/MiddleWare.cpp
@@ -51,9 +51,6 @@ static map_analyzer_actions_and_reporters_t s_mapAnalyzerActionsAndReporters;
static vector_pair_string_string_t s_vectorActionsAndReporters;
-static void RunAnalyzerActions(const char *pAnalyzer, const char* pPackageName, const char *pDebugDumpDir, int force);
-
-
/**
* Transforms a debugdump directory to inner crash
* report form. This form is used for later reporting.
@@ -103,23 +100,11 @@ static std::string GetGlobalUUID(const char *pAnalyzer,
throw CABRTException(EXCEP_PLUGIN, "Error running '%s'", pAnalyzer);
}
-/**
- * Take care of getting all additional data needed
- * for computing UUIDs and creating a report for particular analyzer
- * plugin. This report could be send somewhere afterwards.
- * @param pAnalyzer A name of an analyzer plugin.
- * @param pDebugDumpPath A debugdump dir containing all necessary data.
- */
-static void run_analyzer_CreateReport(const char *pAnalyzer,
- const char *pDebugDumpDir,
- int force)
+static char *do_log_and_update_client(char *log_line, void *param)
{
- CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(pAnalyzer);
- if (analyzer)
- {
- analyzer->CreateReport(pDebugDumpDir, force);
- }
- /* else: GetAnalyzer() already complained, no need to handle it here */
+ VERB1 log("%s", log_line);
+ update_client("%s", log_line);
+ return log_line;
}
/*
@@ -159,32 +144,16 @@ mw_result_t CreateCrashReport(const char *crash_id,
try
{
- struct dump_dir *dd = dd_opendir(row->db_dump_dir, /*flags:*/ 0);
- if (!dd)
+ struct run_event_state *run_state = new_run_event_state();
+ run_state->logging_callback = do_log_and_update_client;
+ int res = run_event(run_state, row->db_dump_dir, "analyze");
+ free_run_event_state(run_state);
+ if (res != 0)
{
- r = MW_ERROR;
+ r = MW_PLUGIN_ERROR;
goto ret;
}
- 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);
- char* package_name = get_package_name_from_NVR_or_NULL(package);
-
- /* Run analyzer's CreateReport() method */
- VERB3 log(" run_analyzer_CreateReport('%s')", analyzer.c_str());
- run_analyzer_CreateReport(analyzer.c_str(), row->db_dump_dir, force);
-
- /* Run actions (only actions, not reporters!) from
- * "ANALYZER[:COMPONENT] = ACTION1, REPORTER1, REPORTER2, ACTION2..." line
- * in abrt.conf
- */
- VERB3 log(" RunAnalyzerActions('%s','%s','%s',force=%d)", analyzer.c_str(), package_name, row->db_dump_dir, force);
- RunAnalyzerActions(analyzer.c_str(), package_name, row->db_dump_dir, force);
- free(package_name);
-
/* Do a load_crash_data_from_debug_dump from (possibly updated)
* crash dump dir
*/
@@ -469,41 +438,6 @@ static bool is_debug_dump_saved(const char *debug_dump_dir)
return row != NULL;
}
-/**
- * Get a package name from executable name and save
- * package description to particular debugdump directory of a crash.
- * @param pExecutable A name of crashed application.
- * @param pDebugDumpDir A debugdump dir containing all necessary data.
- * @return It return results of operation. See mw_result_t.
- */
-static mw_result_t SavePackageDescriptionToDebugDump(const char *pDebugDumpDir)
-{
- pid_t pid = fork();
- if (pid < 0)
- {
- perror_msg("fork");
- return MW_ERROR;
- }
- if (pid == 0) /* child */
- {
- char *argv[5]; /* abrt-action-save-package-data [-s] -d DIR NULL */
- char **pp = argv;
- *pp++ = (char*)"abrt-action-save-package-data";
- if (logmode & LOGMODE_SYSLOG)
- *pp++ = (char*)"-s";
- *pp++ = (char*)"-d";
- *pp++ = (char*)pDebugDumpDir;
- *pp = NULL;
-
- execvp(argv[0], argv);
- perror_msg_and_die("Can't execute '%s'", argv[0]);
- }
- /* parent */
- int status;
- waitpid(pid, &status, 0);
- return (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? MW_OK : MW_ERROR;
-}
-
bool analyzer_has_InformAllUsers(const char *analyzer_name)
{
CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(analyzer_name);
@@ -519,59 +453,6 @@ bool analyzer_has_InformAllUsers(const char *analyzer_name)
}
/**
- * Execute all action plugins, which are associated to
- * particular analyzer plugin.
- * @param pAnalyzer A name of an analyzer plugin.
- * @param pDebugDumpPath A debugdump dir containing all necessary data.
- */
-static void RunAnalyzerActions(const char *pAnalyzer, const char *pPackageName, const char *pDebugDumpDir, int force)
-{
- map_analyzer_actions_and_reporters_t::iterator analyzer;
- if (pPackageName != NULL)
- {
- /*try to find analyzer:component first*/
- char *analyzer_component = xasprintf("%s:%s", pAnalyzer, pPackageName);
- analyzer = s_mapAnalyzerActionsAndReporters.find(analyzer_component);
- /* if we didn't find an action for specific package, use the generic one */
- if (analyzer == s_mapAnalyzerActionsAndReporters.end())
- {
- VERB2 log("didn't find action for %s, trying just %s", analyzer_component, pAnalyzer);
- map_analyzer_actions_and_reporters_t::iterator analyzer = s_mapAnalyzerActionsAndReporters.find(pAnalyzer);
- }
- free(analyzer_component);
- }
- else
- {
- VERB2 log("no package name specified, trying to find action for: %s", pAnalyzer);
- analyzer = s_mapAnalyzerActionsAndReporters.find(pAnalyzer);
- }
- if (analyzer != s_mapAnalyzerActionsAndReporters.end())
- {
- vector_pair_string_string_t::iterator it_a = analyzer->second.begin();
- for (; it_a != analyzer->second.end(); it_a++)
- {
- const char *plugin_name = it_a->first.c_str();
- CAction* action = g_pPluginManager->GetAction(plugin_name, /*silent:*/ true);
- if (!action)
- {
- /* GetAction() already complained if no such plugin.
- * If plugin exists but isn't an Action, it's not an error.
- */
- continue;
- }
- try
- {
- action->Run(pDebugDumpDir, it_a->second.c_str(), force);
- }
- catch (CABRTException& e)
- {
- update_client("Action performed by '%s' was not successful: %s", plugin_name, e.what());
- }
- }
- }
-}
-
-/**
* Save a debugdump into database. If saving is
* successful, then crash info is filled. Otherwise the crash info is
* not changed.
diff --git a/src/daemon/abrt_event.conf b/src/daemon/abrt_event.conf
index a8df2896..5459ddfa 100644
--- a/src/daemon/abrt_event.conf
+++ b/src/daemon/abrt_event.conf
@@ -36,11 +36,13 @@ EVENT=post-create analyzer=oops abrt-action-analyze-oops
# user interaction, uncomment this line:
#EVENT=post-create analyzer=oops abrt-action-kerneloops
+#TODO: implement this (or add this functionality to abrt-action-install-debuginfo):
+#EVENT=analyze analyzer=CCpp trim-debuginfo-cache /var/cache/abrt-di 4096m
EVENT=analyze analyzer=CCpp abrt-action-install-debuginfo "$DUMP_DIR/coredump" "/var/run/abrt/$$-$RANDOM" /var/cache/abrt-di
EVENT=analyze analyzer=CCpp abrt-action-generate-backtrace
-EVENT=report analyzer=oops abrt-action-kerneloops
-EVENT=report_Bugzilla analyzer=CCpp abrt-action-bugzilla
-EVENT=report_Logger analyzer=CCpp abrt-action-print >/var/log/abrt.log
-EVENT=report_Bugzilla analyzer=python abrt-action-bugzilla
-EVENT=report_Logger analyzer=python abrt-action-print >/var/log/abrt.log
+EVENT=report analyzer=oops abrt-action-kerneloops
+EVENT=report_Bugzilla analyzer=CCpp abrt-action-bugzilla
+EVENT=report_Logger analyzer=CCpp abrt-action-print >/var/log/abrt.log
+EVENT=report_Bugzilla analyzer=python abrt-action-bugzilla
+EVENT=report_Logger analyzer=python abrt-action-print >/var/log/abrt.log