diff options
| author | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-01-21 21:20:33 +0100 |
|---|---|---|
| committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-01-21 21:20:33 +0100 |
| commit | ce57d1299f6dadecb36c597e35c00de79d00c5f4 (patch) | |
| tree | 0a900704b79558b4f1683debc9b36fd62b2f2c5b /src | |
| parent | f750288769b23497ad5b57b1c50f683402c509f6 (diff) | |
| parent | 4b54f9866f0dbdc859e300b0169b6ef504ee6c12 (diff) | |
Merge branch 'master' into rhel6
Conflicts:
src/Daemon/abrt.conf
Diffstat (limited to 'src')
| -rw-r--r-- | src/CLI/ABRTSocket.cpp | 6 | ||||
| -rw-r--r-- | src/CLI/ABRTSocket.h | 6 | ||||
| -rw-r--r-- | src/CLI/CLI.cpp | 24 | ||||
| -rw-r--r-- | src/CLI/dbus.cpp | 10 | ||||
| -rw-r--r-- | src/CLI/dbus.h | 6 | ||||
| -rw-r--r-- | src/CLI/report.cpp | 41 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerDBus.cpp | 18 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerSocket.cpp | 17 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerSocket.h | 4 | ||||
| -rw-r--r-- | src/Daemon/CrashWatcher.cpp | 18 | ||||
| -rw-r--r-- | src/Daemon/CrashWatcher.h | 4 | ||||
| -rw-r--r-- | src/Daemon/Daemon.cpp | 26 | ||||
| -rw-r--r-- | src/Daemon/MiddleWare.cpp | 330 | ||||
| -rw-r--r-- | src/Daemon/MiddleWare.h | 18 | ||||
| -rw-r--r-- | src/Daemon/Settings.cpp | 7 | ||||
| -rw-r--r-- | src/Daemon/abrt.conf | 6 | ||||
| -rw-r--r-- | src/Gui/CCDump.py | 61 | ||||
| -rw-r--r-- | src/Gui/CCMainWindow.py | 37 | ||||
| -rw-r--r-- | src/Gui/CCReporterDialog.py | 173 | ||||
| -rw-r--r-- | src/Gui/CC_gui_functions.py | 11 | ||||
| -rw-r--r-- | src/Gui/PluginList.py | 5 | ||||
| -rw-r--r-- | src/Gui/report.glade | 143 | ||||
| -rw-r--r-- | src/Hooks/abrt-hook-ccpp.cpp | 4 | ||||
| -rw-r--r-- | src/Hooks/abrt-hook-python.cpp | 9 | ||||
| -rw-r--r-- | src/Hooks/hooklib.cpp | 4 |
25 files changed, 507 insertions, 481 deletions
diff --git a/src/CLI/ABRTSocket.cpp b/src/CLI/ABRTSocket.cpp index 1353134..82c304e 100644 --- a/src/CLI/ABRTSocket.cpp +++ b/src/CLI/ABRTSocket.cpp @@ -106,7 +106,7 @@ void CABRTSocket::Disconnect() close(m_nSocket); } -vector_crash_infos_t CABRTSocket::GetCrashInfos() +vector_map_crash_data_t CABRTSocket::GetCrashInfos() { std::string message = MESSAGE_GET_CRASH_INFOS; Send(message); @@ -115,7 +115,7 @@ vector_crash_infos_t CABRTSocket::GetCrashInfos() return string_to_crash_infos(message); } -map_crash_report_t CABRTSocket::CreateReport(const std::string &pUUID) +map_crash_data_t CABRTSocket::CreateReport(const std::string &pUUID) { std::string message = MESSAGE_CREATE_REPORT + pUUID; Send(message); @@ -124,7 +124,7 @@ map_crash_report_t CABRTSocket::CreateReport(const std::string &pUUID) return string_to_crash_report(message); } -void CABRTSocket::Report(const map_crash_report_t& pReport) +void CABRTSocket::Report(const map_crash_data_t& pReport) { std::string message = MESSAGE_REPORT + crash_report_to_string(pReport); Send(message); diff --git a/src/CLI/ABRTSocket.h b/src/CLI/ABRTSocket.h index c3a63e5..d4905be 100644 --- a/src/CLI/ABRTSocket.h +++ b/src/CLI/ABRTSocket.h @@ -20,9 +20,9 @@ class CABRTSocket void Connect(const char *pPath); void Disconnect(); - vector_crash_infos_t GetCrashInfos(); - map_crash_report_t CreateReport(const char *pUUID); - void Report(const map_crash_report_t& pReport); + vector_map_crash_data_t GetCrashInfos(); + map_crash_data_t CreateReport(const char *pUUID); + void Report(const map_crash_data_t& pReport); int32_t DeleteDebugDump(const char *pUUID); }; diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index bc8ddf6..a8786e9 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -47,15 +47,15 @@ enum OPT_DELETE }; -static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) +static void print_crash_infos(vector_map_crash_data_t& pCrashInfos, int pMode) { unsigned int ii; for (ii = 0; ii < pCrashInfos.size(); ii++) { - map_crash_info_t& info = pCrashInfos[ii]; - if (pMode == OPT_GET_LIST_FULL || info[CD_REPORTED][CD_CONTENT] != "1") + map_crash_data_t& info = pCrashInfos[ii]; + if (pMode == OPT_GET_LIST_FULL || get_crash_data_item_content(info, CD_REPORTED) != "1") { - const char *timestr = info[CD_TIME][CD_CONTENT].c_str(); + const char *timestr = get_crash_data_item_content(info, FILENAME_TIME).c_str(); long time = strtol(timestr, NULL, 10); if (time == 0) error_msg_and_die("Error while converting time string."); @@ -72,13 +72,13 @@ static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) "\tExecutable : %s\n" "\tCrash Time : %s\n" "\tCrash Count: %s\n"), - ii, - info[CD_UID][CD_CONTENT].c_str(), - info[CD_UUID][CD_CONTENT].c_str(), - info[CD_PACKAGE][CD_CONTENT].c_str(), - info[CD_EXECUTABLE][CD_CONTENT].c_str(), - timeloc, - info[CD_COUNT][CD_CONTENT].c_str() + ii, + get_crash_data_item_content(info, FILENAME_UID).c_str(), + get_crash_data_item_content(info, CD_UUID).c_str(), + get_crash_data_item_content(info, FILENAME_PACKAGE).c_str(), + get_crash_data_item_content(info, FILENAME_EXECUTABLE).c_str(), + timeloc, + get_crash_data_item_content(info, CD_COUNT).c_str() ); } } @@ -189,7 +189,7 @@ int main(int argc, char** argv) case OPT_GET_LIST: case OPT_GET_LIST_FULL: { - vector_crash_infos_t ci = call_GetCrashInfos(); + vector_map_crash_data_t ci = call_GetCrashInfos(); print_crash_infos(ci, op); break; } diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp index 0d03c4d..ffd1157 100644 --- a/src/CLI/dbus.cpp +++ b/src/CLI/dbus.cpp @@ -104,7 +104,7 @@ static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) } } -vector_crash_infos_t call_GetCrashInfos() +vector_map_crash_data_t call_GetCrashInfos() { DBusMessage* msg = new_call_msg(__func__ + 5); DBusMessage *reply = send_get_reply_and_unref(msg); @@ -112,7 +112,7 @@ vector_crash_infos_t call_GetCrashInfos() DBusMessageIter in_iter; dbus_message_iter_init(reply, &in_iter); - vector_crash_infos_t argout; + vector_map_crash_data_t argout; int r = load_val(&in_iter, argout); if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ error_msg_and_die("dbus call %s: return type mismatch", __func__ + 5); @@ -121,7 +121,7 @@ vector_crash_infos_t call_GetCrashInfos() return argout; } -map_crash_report_t call_CreateReport(const char* uuid) +map_crash_data_t call_CreateReport(const char* uuid) { DBusMessage* msg = new_call_msg(__func__ + 5); dbus_message_append_args(msg, @@ -133,7 +133,7 @@ map_crash_report_t call_CreateReport(const char* uuid) DBusMessageIter in_iter; dbus_message_iter_init(reply, &in_iter); - map_crash_report_t argout; + map_crash_data_t argout; int r = load_val(&in_iter, argout); if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ error_msg_and_die("dbus call %s: return type mismatch", __func__ + 5); @@ -142,7 +142,7 @@ map_crash_report_t call_CreateReport(const char* uuid) return argout; } -report_status_t call_Report(const map_crash_report_t& report) +report_status_t call_Report(const map_crash_data_t& report) { DBusMessage* msg = new_call_msg(__func__ + 5); DBusMessageIter out_iter; diff --git a/src/CLI/dbus.h b/src/CLI/dbus.h index c692e19..c6fd7a4 100644 --- a/src/CLI/dbus.h +++ b/src/CLI/dbus.h @@ -23,9 +23,9 @@ extern DBusConnection* s_dbus_conn; -vector_crash_infos_t call_GetCrashInfos(); -map_crash_report_t call_CreateReport(const char *uuid); -report_status_t call_Report(const map_crash_report_t& report); +vector_map_crash_data_t call_GetCrashInfos(); +map_crash_data_t call_CreateReport(const char *uuid); +report_status_t call_Report(const map_crash_data_t& report); int32_t call_DeleteDebugDump(const char* uuid); #ifdef UNUSED diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index bc8f900..76cd3d5 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -19,7 +19,8 @@ #include "run-command.h" #include "dbus.h" #include "abrtlib.h" -#include "DebugDump.h" // FILENAME_* defines +#include "DebugDump.h" +#include "CrashTypes.h" // FILENAME_* defines #if HAVE_CONFIG_H # include <config.h> #endif @@ -151,10 +152,10 @@ static void remove_comments_and_unescape(char *str) * Writes a field of crash report to a file. * Field must be writable. */ -static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, +static void write_crash_report_field(FILE *fp, const map_crash_data_t &report, const char *field, const char *description) { - const map_crash_report_t::const_iterator it = report.find(field); + const map_crash_data_t::const_iterator it = report.find(field); if (it == report.end()) { // exit silently, all fields are optional for now @@ -186,22 +187,22 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, * If the report is successfully stored to the file, a zero value is returned. * On failure, nonzero value is returned. */ -static void write_crash_report(const map_crash_report_t &report, FILE *fp) +static void write_crash_report(const map_crash_data_t &report, FILE *fp) { fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); - write_crash_report_field(fp, report, CD_COMMENT, + write_crash_report_field(fp, report, FILENAME_COMMENT, _("# Describe the circumstances of this crash below.")); - write_crash_report_field(fp, report, CD_REPRODUCE, + write_crash_report_field(fp, report, FILENAME_REPRODUCE, _("# How to reproduce the crash?")); - write_crash_report_field(fp, report, "backtrace", + write_crash_report_field(fp, report, FILENAME_BACKTRACE, _("# Stack trace: a list of active stack frames at the time the crash occurred\n# Check that it does not contain any sensitive data such as passwords.")); - write_crash_report_field(fp, report, CD_UUID, _("# UUID")); + write_crash_report_field(fp, report, CD_DUPHASH, "# DUPHASH"); write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture")); - write_crash_report_field(fp, report, "cmdline", _("# Command line")); + write_crash_report_field(fp, report, FILENAME_CMDLINE, _("# Command line")); write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component")); - write_crash_report_field(fp, report, "coredump", _("# Core dump")); + write_crash_report_field(fp, report, FILENAME_COREDUMP, _("# Core dump")); write_crash_report_field(fp, report, FILENAME_EXECUTABLE, _("# Executable")); write_crash_report_field(fp, report, FILENAME_KERNEL, _("# Kernel version")); write_crash_report_field(fp, report, FILENAME_PACKAGE, _("# Package")); @@ -217,7 +218,7 @@ static void write_crash_report(const map_crash_report_t &report, FILE *fp) * 1 if the field was changed. * Changes to read-only fields are ignored. */ -static int read_crash_report_field(const char *text, map_crash_report_t &report, +static int read_crash_report_field(const char *text, map_crash_data_t &report, const char *field) { char separator[strlen("\n" FIELD_SEP) + strlen(field) + 2]; // 2 = '\n\0' @@ -234,7 +235,7 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, else length = end - textfield; - const map_crash_report_t::iterator it = report.find(field); + const map_crash_data_t::iterator it = report.find(field); if (it == report.end()) { error_msg("Field %s not found.\n", field); @@ -278,17 +279,17 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, * 1 if any field was changed. * Changes to read-only fields are ignored. */ -static int read_crash_report(map_crash_report_t &report, const char *text) +static int read_crash_report(map_crash_data_t &report, const char *text) { int result = 0; - result |= read_crash_report_field(text, report, CD_COMMENT); - result |= read_crash_report_field(text, report, CD_REPRODUCE); - result |= read_crash_report_field(text, report, "backtrace"); - result |= read_crash_report_field(text, report, CD_UUID); + result |= read_crash_report_field(text, report, FILENAME_COMMENT); + result |= read_crash_report_field(text, report, FILENAME_REPRODUCE); + result |= read_crash_report_field(text, report, FILENAME_BACKTRACE); + result |= read_crash_report_field(text, report, CD_DUPHASH); result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE); - result |= read_crash_report_field(text, report, "cmdline"); + result |= read_crash_report_field(text, report, FILENAME_CMDLINE); result |= read_crash_report_field(text, report, FILENAME_COMPONENT); - result |= read_crash_report_field(text, report, "coredump"); + result |= read_crash_report_field(text, report, FILENAME_COREDUMP); result |= read_crash_report_field(text, report, FILENAME_EXECUTABLE); result |= read_crash_report_field(text, report, FILENAME_KERNEL); result |= read_crash_report_field(text, report, FILENAME_PACKAGE); @@ -331,7 +332,7 @@ static int launch_editor(const char *path) int report(const char *uuid, bool always) { // Ask for an initial report. - map_crash_report_t cr = call_CreateReport(uuid); + map_crash_data_t cr = call_CreateReport(uuid); //TODO: error check? if (!always) diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp index 182aa6c..f1f10e5 100644 --- a/src/Daemon/CommLayerServerDBus.cpp +++ b/src/Daemon/CommLayerServerDBus.cpp @@ -133,7 +133,7 @@ static long get_remote_uid(DBusMessage* call, const char** ppSender = NULL) static int handle_GetCrashInfos(DBusMessage* call, DBusMessage* reply) { long unix_uid = get_remote_uid(call); - vector_crash_infos_t argout1 = GetCrashInfos(to_string(unix_uid).c_str()); + vector_map_crash_data_t argout1 = GetCrashInfos(to_string(unix_uid).c_str()); DBusMessageIter out_iter; dbus_message_iter_init_append(reply, &out_iter); @@ -190,7 +190,8 @@ static int handle_CreateReport(DBusMessage* call, DBusMessage* reply) } long unix_uid = get_remote_uid(call); - map_crash_report_t report = CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0); + map_crash_data_t report; + CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0, report); DBusMessageIter out_iter; dbus_message_iter_init_append(reply, &out_iter); @@ -206,7 +207,7 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) DBusMessageIter in_iter; dbus_message_iter_init(call, &in_iter); - map_crash_report_t argin1; + map_crash_data_t argin1; r = load_val(&in_iter, argin1); if (r == ABRT_DBUS_ERROR) { @@ -214,9 +215,9 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) return -1; } - map_crash_report_t::const_iterator it_comment = argin1.find(CD_COMMENT); - map_crash_report_t::const_iterator it_reproduce = argin1.find(CD_REPRODUCE); + map_crash_data_t::const_iterator it_comment = argin1.find(FILENAME_COMMENT); const char* comment = (it_comment != argin1.end()) ? it_comment->second[CD_CONTENT].c_str() : ""; + map_crash_data_t::const_iterator it_reproduce = argin1.find(FILENAME_REPRODUCE); const char* reproduce = (it_reproduce != argin1.end()) ? it_reproduce->second[CD_CONTENT].c_str() : ""; const char* errmsg = NULL; if (strlen(comment) > LIMIT_MESSAGE) @@ -249,15 +250,14 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) } } +#if 0 //const char * sender = dbus_message_get_sender(call); if (!user_conf_data.empty()) { - std::string PluginName; map_map_string_t::const_iterator it_user_conf_data = user_conf_data.begin(); for (; it_user_conf_data != user_conf_data.end(); it_user_conf_data++) { - PluginName = it_user_conf_data->first; -#if DEBUG + std::string PluginName = it_user_conf_data->first; std::cout << "plugin name: " << it_user_conf_data->first; map_string_t::const_iterator it_plugin_config; for (it_plugin_config = it_user_conf_data->second.begin(); @@ -266,11 +266,11 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) { std::cout << " key: " << it_plugin_config->first << " value: " << it_plugin_config->second << std::endl; } -#endif // this would overwrite the default settings //g_pPluginManager->SetPluginSettings(PluginName, sender, plugin_settings); } } +#endif long unix_uid = get_remote_uid(call); report_status_t argout1; diff --git a/src/Daemon/CommLayerServerSocket.cpp b/src/Daemon/CommLayerServerSocket.cpp index 0c5f2e3..ab880fb 100644 --- a/src/Daemon/CommLayerServerSocket.cpp +++ b/src/Daemon/CommLayerServerSocket.cpp @@ -130,14 +130,14 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan if (!strncmp(pMessage.c_str(), MESSAGE_GET_CRASH_INFOS, sizeof(MESSAGE_GET_CRASH_INFOS) - 1)) { - vector_crash_infos_t crashInfos = GetCrashInfos(UID); + vector_map_crash_data_t crashInfos = GetCrashInfos(UID); std::string message = MESSAGE_GET_CRASH_INFOS + crash_infos_to_string(crashInfos); Send(message, pSource); } else if (!strncmp(pMessage.c_str(), MESSAGE_REPORT, sizeof(MESSAGE_REPORT) - 1)) { std::string message = pMessage.substr(sizeof(MESSAGE_REPORT) - 1); - map_crash_report_t report = string_to_crash_report(message); + map_crash_data_t report = string_to_crash_report(message); map_plugin_settings_t plugin_settings; //FIXME: another hack to make this compile // Report(report, plugin_settings, UID); @@ -145,7 +145,8 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan else if (!strncmp(pMessage.c_str(), MESSAGE_CREATE_REPORT, sizeof(MESSAGE_CREATE_REPORT) - 1)) { // std::string UUID = pMessage.substr(sizeof(MESSAGE_CREATE_REPORT) - 1); -// map_crash_report_t crashReport = CreateReport(UUID, UID); +// map_crash_data_t crashReport; +// CreateReport(UUID, UID, crashReport); //use CreateReportThread instead of CreateReport? // std::string message = MESSAGE_CREATE_REPORT + crash_report_to_string(crashReport); // Send(message, pSource); @@ -211,22 +212,22 @@ CCommLayerServerSocket::~CCommLayerServerSocket() close(m_nSocket); } -vector_crash_infos_t CCommLayerServerSocket::GetCrashInfos(const std::string &pSender) +vector_map_crash_data_t CCommLayerServerSocket::GetCrashInfos(const std::string &pSender) { - vector_crash_infos_t crashInfos; + vector_map_crash_data_t crashInfos; crashInfos = ::GetCrashInfos(pSender); return crashInfos; } //reimplement as CreateReportThread(...)? -//map_crash_report_t CCommLayerServerSocket::CreateReport(const std::string &pUUID, const std::string &pSender) +//map_crash_data_t CCommLayerServerSocket::CreateReport(const std::string &pUUID, const std::string &pSender) //{ -// map_crash_report_t crashReport; +// map_crash_data_t crashReport; // crashReport = ::CreateReport(pUUID, pSender); // return crashReport; //} -report_status_t CCommLayerServerSocket::Report(const map_crash_report_t& pReport, const std::string& pSender) +report_status_t CCommLayerServerSocket::Report(const map_crash_data_t& pReport, const std::string& pSender) { report_status_t rs; //FIXME: a hack to make this compile, but we don't use sockets anyway diff --git a/src/Daemon/CommLayerServerSocket.h b/src/Daemon/CommLayerServerSocket.h index 753b67a..c511954 100644 --- a/src/Daemon/CommLayerServerSocket.h +++ b/src/Daemon/CommLayerServerSocket.h @@ -26,8 +26,8 @@ class CCommLayerServerSocket : public CCommLayerServer CCommLayerServerSocket(); virtual ~CCommLayerServerSocket(); - virtual vector_crash_infos_t GetCrashInfos(const char *pSender); - virtual report_status_t Report(const map_crash_report_t& pReport, const char *pSender); + virtual vector_map_crash_data_t GetCrashInfos(const char *pSender); + virtual report_status_t Report(const map_crash_data_t& pReport, const char *pSender); virtual void DeleteDebugDump(const char *pUUID, const char *pSender); virtual void Crash(const char *arg1); diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp index 59f9e65..93365f3 100644 --- a/src/Daemon/CrashWatcher.cpp +++ b/src/Daemon/CrashWatcher.cpp @@ -45,9 +45,9 @@ CCrashWatcher::~CCrashWatcher() { } -vector_crash_infos_t GetCrashInfos(const char *pUID) +vector_map_crash_data_t GetCrashInfos(const char *pUID) { - vector_crash_infos_t retval; + vector_map_crash_data_t retval; log("Getting crash infos..."); try { @@ -57,12 +57,11 @@ vector_crash_infos_t GetCrashInfos(const char *pUID) unsigned int ii; for (ii = 0; ii < UUIDsUIDs.size(); ii++) { - mw_result_t res; - map_crash_info_t info; const char *uuid = UUIDsUIDs[ii].first.c_str(); const char *uid = UUIDsUIDs[ii].second.c_str(); - res = FillCrashInfo(uuid, uid, info); + map_crash_data_t info; + mw_result_t res = FillCrashInfo(uuid, uid, info); switch (res) { case MW_OK: @@ -96,10 +95,8 @@ vector_crash_infos_t GetCrashInfos(const char *pUID) * StartJob dbus call already did all the processing, and we just retrieve * the result from dump directory, which is fast. */ -map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) +void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t& crashReport) { - map_crash_info_t crashReport; - /* FIXME: starting from here, any shared data must be protected with a mutex. * For example, CreateCrashReport does: * g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); @@ -109,6 +106,7 @@ map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) switch (res) { case MW_OK: + VERB2 log_map_crash_data(crashReport, "crashReport"); break; case MW_IN_DB_ERROR: error_msg("Can't find crash with UUID %s in database", pUUID); @@ -121,7 +119,6 @@ map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) DeleteDebugDump(pUUID, pUID); break; } - return crashReport; } typedef struct thread_data_t { @@ -141,7 +138,8 @@ static void* create_report(void* arg) try { log("Creating report..."); - map_crash_info_t crashReport = CreateReport(thread_data->UUID, thread_data->UID, thread_data->force); + map_crash_data_t crashReport; + CreateReport(thread_data->UUID, thread_data->UID, thread_data->force, crashReport); g_pCommLayer->JobDone(thread_data->peer, thread_data->UUID); } catch (CABRTException& e) diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h index 8d56c4e..31b72e0 100644 --- a/src/Daemon/CrashWatcher.h +++ b/src/Daemon/CrashWatcher.h @@ -48,9 +48,9 @@ class CCrashWatcher virtual void Warning(const char *pMessage, const char* peer, uint64_t pJobID); }; -vector_crash_infos_t GetCrashInfos(const char *pUID); +vector_map_crash_data_t GetCrashInfos(const char *pUID); int CreateReportThread(const char* pUUID, const char* pUID, int force, const char* pSender); -map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force); +void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t&); int DeleteDebugDump(const char *pUUID, const char *pUID); void DeleteDebugDump_by_dir(const char *dump_dir); diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index dc547af..83b1cee 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -51,15 +51,15 @@ * - signal: we got SIGTERM or SIGINT * * DBus methods we have: - * - GetCrashInfos(): returns a vector_crash_infos_t (vector_map_vector_string_t) + * - GetCrashInfos(): returns a vector_map_crash_data_t (vector_map_vector_string_t) * of crashes for given uid * v[N]["executable"/"uid"/"kernel"/"backtrace"][N] = "contents" * - StartJob(UUID,force): starts creating a report for /var/cache/abrt/DIR with this UUID. * Returns job id (uint64). * After thread returns, when report creation thread has finished, * JobDone(client_dbus_ID,UUID) dbus signal is emitted. - * - CreateReport(UUID): returns map_crash_report_t (map_vector_string_t) - * - Report(map_crash_report_t (map_vector_string_t[, map_map_string_t])): + * - CreateReport(UUID): returns map_crash_data_t (map_vector_string_t) + * - Report(map_crash_data_t (map_vector_string_t[, map_map_string_t])): * "Please report this crash": calls Report() of all registered reporter plugins. * Returns report_status_t (map_vector_string_t) - the status of each call. * 2nd parameter is the contents of user's abrt.conf. @@ -320,15 +320,15 @@ static void FindNewDumps(const char* pPath) vector_string_t::iterator itt = dirs.begin(); for (; itt != dirs.end(); ++itt) { - map_crash_info_t crashinfo; try { + map_crash_data_t crashinfo; mw_result_t res = SaveDebugDump(itt->c_str(), crashinfo); switch (res) { case MW_OK: VERB1 log("Saving %s into database", itt->c_str()); - RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str()); + RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str()); break; case MW_IN_DB: VERB1 log("%s is already saved in database", itt->c_str()); @@ -476,17 +476,17 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin worst_dir = ""; } - map_crash_info_t crashinfo; try { std::string fullname = concat_path_file(DEBUG_DUMPS_DIR, name); - +//todo: rename SaveDebugDump to ???? it does not save crashinfo, it FETCHES crashinfo + map_crash_data_t crashinfo; mw_result_t res = SaveDebugDump(fullname.c_str(), crashinfo); switch (res) { case MW_OK: log("New crash, saving"); - RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str()); + RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str()); /* Fall through */ case MW_REPORTED: case MW_OCCURED: @@ -494,16 +494,16 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin if (res != MW_OK) log("Already saved crash, just sending dbus signal"); - const char *analyzer = crashinfo[CD_MWANALYZER][CD_CONTENT].c_str(); - const char *uid_str = crashinfo[CD_UID][CD_CONTENT].c_str(); + const char *analyzer = get_crash_data_item_content(crashinfo, FILENAME_ANALYZER).c_str(); + const char *uid_str = get_crash_data_item_content(crashinfo, FILENAME_UID).c_str(); /* Autoreport it if configured to do so */ if (analyzer_has_AutoReportUIDs(analyzer, uid_str)) { VERB1 log("Reporting the crash automatically"); - map_crash_report_t crash_report; + map_crash_data_t crash_report; mw_result_t crash_result = CreateCrashReport( - crashinfo[CD_UUID][CD_CONTENT].c_str(), + get_crash_data_item_content(crashinfo, CD_UUID).c_str(), uid_str, /*force:*/ 0, crash_report ); if (crash_result == MW_OK) @@ -525,7 +525,7 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin /* Send dbus signal */ if (analyzer_has_InformAllUsers(analyzer)) uid_str = NULL; - g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT].c_str(), uid_str); + g_pCommLayer->Crash(get_crash_data_item_content(crashinfo, FILENAME_PACKAGE).c_str(), uid_str); break; } case MW_BLACKLISTED: diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp index c2a122a..9abb737 100644 --- a/src/Daemon/MiddleWare.cpp +++ b/src/Daemon/MiddleWare.cpp @@ -85,8 +85,8 @@ static char* is_text_file(const char *name, ssize_t *sz) } /* Some files in our dump directories are known to always be textual */ - if (strcmp(name, "backtrace") == 0 - || strcmp(name, "cmdline") == 0 + if (strcmp(name, FILENAME_BACKTRACE) == 0 + || strcmp(name, FILENAME_CMDLINE) == 0 ) { return buf; } @@ -120,29 +120,11 @@ static char* is_text_file(const char *name, ssize_t *sz) return NULL; /* it's binary */ } -/** - * Transforms a debugdump direcortry to inner crash - * report form. This form is used for later reporting. - * @param pDebugDumpDir A debugdump dir containing all necessary data. - * @param pCrashReport A created crash report. - */ -static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t& pCrashReport) +static void load_crash_data_from_debug_dump(CDebugDump& dd, map_crash_data_t& data) { - CDebugDump dd; - dd.Open(pDebugDumpDir); - if (!dd.Exist(FILENAME_ARCHITECTURE) - || !dd.Exist(FILENAME_KERNEL) - || !dd.Exist(FILENAME_PACKAGE) - || !dd.Exist(FILENAME_COMPONENT) - || !dd.Exist(FILENAME_RELEASE) - || !dd.Exist(FILENAME_EXECUTABLE) - ) { - throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): One or more of important file(s) are missing"); - } - std::string short_name; std::string full_name; - pCrashReport.clear(); + dd.InitGetNextFile(); while (dd.GetNextFile(&short_name, &full_name)) { @@ -150,11 +132,11 @@ static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t char *text = is_text_file(full_name.c_str(), &sz); if (!text) { - add_crash_data_to_crash_report(pCrashReport, - short_name, - CD_BIN, - CD_ISNOTEDITABLE, - full_name + add_to_crash_data_ext(data, + short_name.c_str(), + CD_BIN, + CD_ISNOTEDITABLE, + full_name.c_str() ); continue; } @@ -166,33 +148,39 @@ static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t dd.LoadText(short_name.c_str(), content); free(text); - if (short_name == FILENAME_ARCHITECTURE - || short_name == FILENAME_KERNEL - || short_name == FILENAME_PACKAGE - || short_name == FILENAME_COMPONENT - || short_name == FILENAME_RELEASE - || short_name == FILENAME_EXECUTABLE - ) { - add_crash_data_to_crash_report(pCrashReport, short_name, CD_TXT, CD_ISNOTEDITABLE, content); - continue; - } + add_to_crash_data_ext(data, + short_name.c_str(), + CD_TXT, + is_editable_file(short_name.c_str()) ? CD_ISEDITABLE : CD_ISNOTEDITABLE, + content.c_str() + ); + } +} - if (short_name != FILENAME_UID - && short_name != FILENAME_ANALYZER - && short_name != FILENAME_TIME - && short_name != FILENAME_DESCRIPTION - && short_name != FILENAME_REPRODUCE - && short_name != FILENAME_COMMENT - ) { - add_crash_data_to_crash_report( - pCrashReport, - short_name, - CD_TXT, - CD_ISEDITABLE, - content - ); +/** + * Transforms a debugdump directory to inner crash + * report form. This form is used for later reporting. + * @param pDebugDumpDir A debugdump dir containing all necessary data. + * @param pCrashData A created crash report. + */ +static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_data_t& pCrashData) +{ + VERB3 log(" DebugDumpToCrashReport('%s')", pDebugDumpDir); + + CDebugDump dd; + dd.Open(pDebugDumpDir); + + const char *const *v = must_have_files; + while (*v) + { + if (!dd.Exist(*v)) + { + throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): important file '%s' is missing", *v); } + v++; } + + load_crash_data_from_debug_dump(dd, pCrashData); } /** @@ -235,7 +223,7 @@ static std::string GetGlobalUUID(const char *pAnalyzer, * @param pAnalyzer A name of an analyzer plugin. * @param pDebugDumpPath A debugdump dir containing all necessary data. */ -static void CreateReport(const char *pAnalyzer, +static void run_analyser_CreateReport(const char *pAnalyzer, const char *pDebugDumpDir, int force) { @@ -250,7 +238,7 @@ static void CreateReport(const char *pAnalyzer, mw_result_t CreateCrashReport(const char *pUUID, const char *pUID, int force, - map_crash_report_t& pCrashReport) + map_crash_data_t& pCrashData) { VERB2 log("CreateCrashReport('%s','%s',result)", pUUID, pUID); @@ -268,64 +256,56 @@ mw_result_t CreateCrashReport(const char *pUUID, return MW_IN_DB_ERROR; } + mw_result_t r = MW_OK; try { - CDebugDump dd; - std::string analyzer; - std::string gUUID; - std::string comment; - std::string reproduce = "1.\n2.\n3.\n"; - - VERB3 log(" LoadText(FILENAME_ANALYZER,'%s')", row.m_sDebugDumpDir.c_str()); - dd.Open(row.m_sDebugDumpDir.c_str()); - dd.LoadText(FILENAME_ANALYZER, analyzer); - if (dd.Exist(FILENAME_COMMENT)) - { - dd.LoadText(FILENAME_COMMENT, comment); - } - if (dd.Exist(FILENAME_REPRODUCE)) { - dd.LoadText(FILENAME_REPRODUCE, reproduce); + CDebugDump dd; + dd.Open(row.m_sDebugDumpDir.c_str()); + load_crash_data_from_debug_dump(dd, pCrashData); } - dd.Close(); - VERB3 log(" CreateReport('%s')", analyzer.c_str()); - CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force); + std::string analyzer = get_crash_data_item_content(pCrashData, FILENAME_ANALYZER); - gUUID = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); - VERB3 log(" GetGlobalUUID:'%s'", gUUID.c_str()); + // TODO: explain what run_analyser_CreateReport and RunAnalyzerActions are expected to do. + // Do they potentially add more files to dump dir? + // Why we calculate dup_hash after run_analyser_CreateReport but before RunAnalyzerActions? + // Why do we reload dump dir's data via DebugDumpToCrashReport? - VERB3 log(" RunAnalyzerActions"); + VERB3 log(" run_analyser_CreateReport('%s')", analyzer.c_str()); + run_analyser_CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force); + + std::string dup_hash = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); + VERB3 log(" DUPHASH:'%s'", dup_hash.c_str()); + + VERB3 log(" RunAnalyzerActions('%s','%s')", analyzer.c_str(), row.m_sDebugDumpDir.c_str()); RunAnalyzerActions(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); - VERB3 log(" DebugDumpToCrashReport"); - DebugDumpToCrashReport(row.m_sDebugDumpDir.c_str(), pCrashReport); - add_crash_data_to_crash_report(pCrashReport, CD_UUID, CD_TXT, CD_ISNOTEDITABLE, gUUID); - add_crash_data_to_crash_report(pCrashReport, CD_MWANALYZER, CD_SYS, CD_ISNOTEDITABLE, analyzer); - add_crash_data_to_crash_report(pCrashReport, CD_MWUID, CD_SYS, CD_ISNOTEDITABLE, pUID); - add_crash_data_to_crash_report(pCrashReport, CD_MWUUID, CD_SYS, CD_ISNOTEDITABLE, pUUID); - add_crash_data_to_crash_report(pCrashReport, CD_COMMENT, CD_TXT, CD_ISEDITABLE, comment); - add_crash_data_to_crash_report(pCrashReport, CD_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce); + DebugDumpToCrashReport(row.m_sDebugDumpDir.c_str(), pCrashData); + + add_to_crash_data_ext(pCrashData, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, dup_hash.c_str()); + add_to_crash_data_ext(pCrashData, CD_UUID , CD_SYS, CD_ISNOTEDITABLE, pUUID); } catch (CABRTException& e) { + r = MW_CORRUPTED; error_msg("%s", e.what()); if (e.type() == EXCEP_DD_OPEN) { - return MW_ERROR; + r = MW_ERROR; } - if (e.type() == EXCEP_DD_LOAD) + else if (e.type() == EXCEP_DD_LOAD) { - return MW_FILE_ERROR; + r = MW_FILE_ERROR; } - if (e.type() == EXCEP_PLUGIN) + else if (e.type() == EXCEP_PLUGIN) { - return MW_PLUGIN_ERROR; + r = MW_PLUGIN_ERROR; } - return MW_CORRUPTED; } - return MW_OK; + VERB3 log("CreateCrashReport() returns %d", r); + return r; } void RunAction(const char *pActionDir, @@ -362,7 +342,7 @@ void RunActionsAndReporters(const char *pDebugDumpDir) if (tp == REPORTER) { CReporter* reporter = g_pPluginManager->GetReporter(plugin_name); /* can't be NULL */ - map_crash_report_t crashReport; + map_crash_data_t crashReport; DebugDumpToCrashReport(pDebugDumpDir, crashReport); VERB2 log("%s.Report(...)", plugin_name); reporter->Report(crashReport, plugin_settings, it_ar->second.c_str()); @@ -382,88 +362,70 @@ void RunActionsAndReporters(const char *pDebugDumpDir) } -static bool CheckReport(const map_crash_report_t& pCrashReport) -{ - map_crash_report_t::const_iterator it_analyzer = pCrashReport.find(CD_MWANALYZER); - map_crash_report_t::const_iterator it_mwuid = pCrashReport.find(CD_MWUID); - map_crash_report_t::const_iterator it_mwuuid = pCrashReport.find(CD_MWUUID); - - map_crash_report_t::const_iterator it_package = pCrashReport.find(FILENAME_PACKAGE); - map_crash_report_t::const_iterator it_architecture = pCrashReport.find(FILENAME_ARCHITECTURE); - map_crash_report_t::const_iterator it_kernel = pCrashReport.find(FILENAME_KERNEL); - map_crash_report_t::const_iterator it_component = pCrashReport.find(FILENAME_COMPONENT); - map_crash_report_t::const_iterator it_release = pCrashReport.find(FILENAME_RELEASE); - map_crash_report_t::const_iterator it_executable = pCrashReport.find(FILENAME_EXECUTABLE); - - map_crash_report_t::const_iterator end = pCrashReport.end(); - - if (it_package == end) - { - return false; - } - - // FIXME: bypass the test if it's kerneloops - if (it_package->second[CD_CONTENT] == "kernel") - return true; - - if (it_analyzer == end || it_mwuid == end || - it_mwuuid == end || /* it_package == end || */ - it_architecture == end || it_kernel == end || - it_component == end || it_release == end || - it_executable == end) - { - return false; - } - - if (it_analyzer->second[CD_CONTENT] == "" || it_mwuid->second[CD_CONTENT] == "" || - it_mwuuid->second[CD_CONTENT] == "" || it_package->second[CD_CONTENT] == "" || - it_architecture->second[CD_CONTENT] == "" || it_kernel->second[CD_CONTENT] == "" || - it_component->second[CD_CONTENT] == "" || it_release->second[CD_CONTENT] == "" || - it_executable->second[CD_CONTENT] == "") - { - return false; - } - - return true; -} - -report_status_t Report(const map_crash_report_t& pCrashReport, +// We must not trust client_report here! +// dbus handler passes it from user without checking +report_status_t Report(const map_crash_data_t& client_report, map_map_string_t& pSettings, const char *pUID) { - report_status_t ret; - - /* dbus handler passes pCrashReport from user without checking it */ - - if (!CheckReport(pCrashReport)) - { - throw CABRTException(EXCEP_ERROR, "Report(): Some of mandatory report data are missing."); - } - - std::string analyzer = pCrashReport.find(CD_MWANALYZER)->second[CD_CONTENT]; - std::string UID = pCrashReport.find(CD_MWUID)->second[CD_CONTENT]; - std::string UUID = pCrashReport.find(CD_MWUUID)->second[CD_CONTENT]; - std::string packageNVR = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1)); - - // Save comment and "how to reproduce" - map_crash_report_t::const_iterator it_comment = pCrashReport.find(CD_COMMENT); - map_crash_report_t::const_iterator it_reproduce = pCrashReport.find(CD_REPRODUCE); - if (it_comment != pCrashReport.end() || it_reproduce != pCrashReport.end()) + // Get ID fields + const char *UID = get_crash_data_item_content_or_NULL(client_report, FILENAME_UID); + const char *UUID = get_crash_data_item_content_or_NULL(client_report, CD_UUID); + if (!UID || !UUID) { + throw CABRTException(EXCEP_ERROR, "Report(): UID or UUID is missing in client's report data"); + } + + // Retrieve corresponding stored record + map_crash_data_t stored_report; + mw_result_t r = FillCrashInfo(UUID, UID, stored_report); + if (r != MW_OK) + return report_status_t(); + const std::string& pDumpDir = get_crash_data_item_content(stored_report, CD_DUMPDIR); + + // Save comment, "how to reproduce", backtrace + const char *comment = get_crash_data_item_content_or_NULL(client_report, FILENAME_COMMENT); + const char *reproduce = get_crash_data_item_content_or_NULL(client_report, FILENAME_REPRODUCE); + const char *backtrace = get_crash_data_item_content_or_NULL(client_report, FILENAME_BACKTRACE); + if (comment || reproduce || backtrace) { - std::string pDumpDir = getDebugDumpDir(UUID.c_str(), UID.c_str()); CDebugDump dd; dd.Open(pDumpDir.c_str()); - if (it_comment != pCrashReport.end()) + if (comment) + { + dd.SaveText(FILENAME_COMMENT, comment); + add_to_crash_data_ext(stored_report, FILENAME_COMMENT, CD_TXT, CD_ISEDITABLE, comment); + } + if (reproduce) { - dd.SaveText(FILENAME_COMMENT, it_comment->second[CD_CONTENT].c_str()); + dd.SaveText(FILENAME_REPRODUCE, reproduce); + add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce); } - if (it_reproduce != pCrashReport.end()) + if (backtrace) { - dd.SaveText(FILENAME_REPRODUCE, it_reproduce->second[CD_CONTENT].c_str()); + dd.SaveText(FILENAME_BACKTRACE, backtrace); + add_to_crash_data_ext(stored_report, FILENAME_BACKTRACE, CD_TXT, CD_ISEDITABLE, backtrace); } } + const std::string& analyzer = get_crash_data_item_content(stored_report, FILENAME_ANALYZER); + + std::string dup_hash = GetGlobalUUID(analyzer.c_str(), pDumpDir.c_str()); + VERB3 log(" DUPHASH:'%s'", dup_hash.c_str()); + add_to_crash_data_ext(stored_report, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, dup_hash.c_str()); + + // Run reporters + + VERB3 { + log("Run reporters"); + log_map_crash_data(client_report, " client_report"); + log_map_crash_data(stored_report, " stored_report"); + } +#define client_report client_report_must_not_be_used_below + + map_crash_data_t::const_iterator its_PACKAGE = stored_report.find(FILENAME_PACKAGE); + std::string packageNVR = its_PACKAGE->second[CD_CONTENT]; + std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1)); + // analyzer with package name (CCpp:xorg-x11-app) has higher priority std::string key = analyzer + ":" + packageName; map_analyzer_actions_and_reporters_t::iterator end = s_mapAnalyzerActionsAndReporters.end(); @@ -475,6 +437,7 @@ report_status_t Report(const map_crash_report_t& pCrashReport, key = analyzer; } + report_status_t ret; std::string message; if (keyPtr != end) { @@ -509,7 +472,7 @@ report_status_t Report(const map_crash_report_t& pCrashReport, } #endif map_plugin_settings_t plugin_settings = pSettings[plugin_name]; - std::string res = reporter->Report(pCrashReport, plugin_settings, it_r->second.c_str()); + std::string res = reporter->Report(stored_report, plugin_settings, it_r->second.c_str()); #if 0 /* Using ~user/.abrt/ is bad wrt security */ if (home != "") @@ -535,10 +498,11 @@ report_status_t Report(const map_crash_report_t& pCrashReport, CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); - database->SetReported(UUID.c_str(), UID.c_str(), message.c_str()); + database->SetReported(UUID, UID, message.c_str()); database->DisConnect(); return ret; +#undef client_report } /** @@ -767,7 +731,7 @@ bool analyzer_has_AutoReportUIDs(const char *analyzer_name, const char* uid) return false; } -void autoreport(const pair_string_string_t& reporter_options, const map_crash_report_t& crash_report) +void autoreport(const pair_string_string_t& reporter_options, const map_crash_data_t& crash_report) { CReporter* reporter = g_pPluginManager->GetReporter(reporter_options.first.c_str()); if (!reporter) @@ -821,14 +785,14 @@ static void RunAnalyzerActions(const char *pAnalyzer, const char *pDebugDumpDir) * @param pUID An UID of an user. * @param pTime Time when a crash occurs. * @param pDebugDumpPath A debugdump path. - * @param pCrashInfo A filled crash info. + * @param pCrashData A filled crash info. * @return It return results of operation. See mw_result_t. */ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, const char *pUID, const char *pTime, const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -837,7 +801,7 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, database_row_t row = database->GetRow(pUUID, pUID); database->DisConnect(); - mw_result_t res = FillCrashInfo(pUUID, pUID, pCrashInfo); + mw_result_t res = FillCrashInfo(pUUID, pUID, pCrashData); if (res == MW_OK) { if (row.m_sReported == "1") @@ -854,8 +818,7 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, return res; } -std::string getDebugDumpDir(const char *pUUID, - const char *pUID) +std::string getDebugDumpDir(const char *pUUID, const char *pUID) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -865,7 +828,7 @@ std::string getDebugDumpDir(const char *pUUID, } mw_result_t SaveDebugDump(const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { std::string UID; std::string time; @@ -907,12 +870,12 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, const char *uid_str = analyzer_has_InformAllUsers(analyzer.c_str()) ? "-1" : UID.c_str(); - return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashInfo); + return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashData); } mw_result_t FillCrashInfo(const char *pUUID, const char *pUID, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -927,10 +890,7 @@ mw_result_t FillCrashInfo(const char *pUUID, { CDebugDump dd; dd.Open(row.m_sDebugDumpDir.c_str()); - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - dd.LoadText(FILENAME_DESCRIPTION, description); - dd.LoadText(FILENAME_ANALYZER, analyzer); + load_crash_data_from_debug_dump(dd, pCrashData); } catch (CABRTException& e) { @@ -938,18 +898,14 @@ mw_result_t FillCrashInfo(const char *pUUID, return MW_ERROR; } - pCrashInfo.clear(); - add_crash_data_to_crash_info(pCrashInfo, CD_EXECUTABLE, executable); - add_crash_data_to_crash_info(pCrashInfo, CD_PACKAGE, package); - add_crash_data_to_crash_info(pCrashInfo, CD_DESCRIPTION, description); - add_crash_data_to_crash_info(pCrashInfo, CD_UUID, row.m_sUUID); - add_crash_data_to_crash_info(pCrashInfo, CD_UID, row.m_sUID); - add_crash_data_to_crash_info(pCrashInfo, CD_COUNT, row.m_sCount); - add_crash_data_to_crash_info(pCrashInfo, CD_TIME, row.m_sTime); - add_crash_data_to_crash_info(pCrashInfo, CD_REPORTED, row.m_sReported); - add_crash_data_to_crash_info(pCrashInfo, CD_MESSAGE, row.m_sMessage); - add_crash_data_to_crash_info(pCrashInfo, CD_MWDDD, row.m_sDebugDumpDir); - add_crash_data_to_crash_info(pCrashInfo, CD_MWANALYZER, analyzer); + add_to_crash_data(pCrashData, CD_UUID , row.m_sUUID.c_str() ); + add_to_crash_data(pCrashData, CD_COUNT , row.m_sCount.c_str() ); + add_to_crash_data(pCrashData, CD_REPORTED , row.m_sReported.c_str() ); + add_to_crash_data(pCrashData, CD_MESSAGE , row.m_sMessage.c_str() ); + add_to_crash_data(pCrashData, CD_DUMPDIR , row.m_sDebugDumpDir.c_str()); +//TODO: why do we keep uid and time in DB and in dumpdir?! + add_to_crash_data(pCrashData, FILENAME_UID , row.m_sUID.c_str() ); + add_to_crash_data(pCrashData, FILENAME_TIME , row.m_sTime.c_str() ); return MW_OK; } diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h index b2b58dc..5fab84d 100644 --- a/src/Daemon/MiddleWare.h +++ b/src/Daemon/MiddleWare.h @@ -60,13 +60,13 @@ void LoadOpenGPGPublicKey(const char* key); * is successful, then a crash report is filled. * @param pAnalyzer A name of an analyzer plugin. * @param pDebugDumpPath A debugdump dir containing all necessary data. - * @param pCrashReport A filled crash report. + * @param pCrashData A filled crash report. * @return It return results of operation. See mw_result_t. */ mw_result_t CreateCrashReport(const char *pUUID, const char *pUID, int force, - map_crash_report_t& pCrashReport); + map_crash_data_t& pCrashData); /** * Activates particular action plugin. * @param pActionDir A directory, which is passed as working to a action plugin. @@ -88,11 +88,11 @@ void RunActionsAndReporters(const char *pDebugDumpDir); * fails, then default config is used. If pUID is emply string, default * config is used. * ...). - * @param pCrashReport A crash report. + * @param pCrashData A crash report. * @param pUID An user uid * @return A report status, which reporters ends successfuly with messages. */ -report_status_t Report(const map_crash_report_t& pCrashReport, +report_status_t Report(const map_crash_data_t& pCrashData, map_map_string_t& pSettings, const char *pUID); /** @@ -108,22 +108,22 @@ std::string getDebugDumpDir( const char *pUUID, * Saves debugdump into database. If saving is successful, * it fills crash info. * @param pDebugDumpDir A debugdump directory. - * @param pCrashInfo A crash info. + * @param pCrashData A crash info. * @return It return results of operation. See mw_result_t. */ mw_result_t SaveDebugDump(const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo); + map_crash_data_t& pCrashData); /** * Get one crash info. If getting is successful, * then crash info is filled. * @param pUUID A local UUID of a crash. * @param pUID An UID of an user. - * @param pCrashInfo A crash info. + * @param pCrashData A crash info. * @return It return results of operation. See mw_result_t. */ mw_result_t FillCrashInfo(const char *pUUID, const char *pUID, - map_crash_info_t& pCrashInfo); + map_crash_data_t& pCrashData); /** * Gets all local UUIDs and UIDs of crashes. These crashes * occurred when a particular user was logged in. @@ -154,5 +154,5 @@ bool analyzer_has_InformAllUsers(const char *analyzer_name); bool analyzer_has_AutoReportUIDs(const char *analyzer_name, const char* uid); -void autoreport(const pair_string_string_t& reporter_options, const map_crash_report_t& crash_report); +void autoreport(const pair_string_string_t& reporter_options, const map_crash_data_t& crash_report); #endif /*MIDDLEWARE_H_*/ diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp index 48658e2..6cf32a6 100644 --- a/src/Daemon/Settings.cpp +++ b/src/Daemon/Settings.cpp @@ -77,7 +77,7 @@ static set_string_t ParseList(const char* pList) return set; } -/* (What format do we parse here?) */ +/* Format: name, name(param),name("param with spaces \"and quotes\"") */ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) { VERB3 log(" ParseListWithArgs(%s)", pValue); @@ -92,7 +92,6 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) { if (is_quote && pValue[ii] == '\\' && pValue[ii+1]) { - item += pValue[ii]; ii++; item += pValue[ii]; continue; @@ -100,7 +99,7 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) if (pValue[ii] == '"') { is_quote = !is_quote; - item += pValue[ii]; + /*item += pValue[ii]; - wrong! name("param") must be == name(param) */ continue; } if (is_quote) @@ -146,8 +145,8 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) static void ParseCommon() { - map_string_t::const_iterator it = s_mapSectionCommon.find("OpenGPGCheck"); map_string_t::const_iterator end = s_mapSectionCommon.end(); + map_string_t::const_iterator it = s_mapSectionCommon.find("OpenGPGCheck"); if (it != end) { g_settings_bOpenGPGCheck = string_to_bool(it->second.c_str()); diff --git a/src/Daemon/abrt.conf b/src/Daemon/abrt.conf index f781184..53e71a3 100644 --- a/src/Daemon/abrt.conf +++ b/src/Daemon/abrt.conf @@ -14,10 +14,11 @@ BlackList = nspluginwrapper Database = SQLite3 # Max size for crash storage [MiB] MaxCrashReportsSize = 1000 -# Vector of actions and reporters which are activated immediately after a crash occurs +# Vector of actions and reporters which are activated immediately after a crash occurs, +# comma separated. #ActionsAndReporters = Mailx("[abrt] new crash was detected") -# What actions or reporters to run on specified crash type +# What actions or reporters to run on each crash type [ AnalyzerActionsAndReporters ] Kerneloops = TicketUploader CCpp = TicketUploader @@ -29,3 +30,4 @@ Python = TicketUploader # h:m - at h:m an action plugin is activated # s - every s seconds is an action plugin activated 120 = KerneloopsScanner +#02:00 = FileTransfer diff --git a/src/Gui/CCDump.py b/src/Gui/CCDump.py index 96d036c..1f29092 100644 --- a/src/Gui/CCDump.py +++ b/src/Gui/CCDump.py @@ -3,20 +3,55 @@ from datetime import datetime from abrt_utils import _, init_logging, log, log1, log2 +# Should match CrashTypes.h! CD_TYPE = 0 CD_EDITABLE = 1 CD_CONTENT = 2 +CD_SYS = "s" +CD_BIN = "b" +CD_TXT = "t" + +FILENAME_ARCHITECTURE = "architecture" +FILENAME_KERNEL = "kernel" +FILENAME_TIME = "time" +FILENAME_UID = "uid" +FILENAME_PACKAGE = "package" +FILENAME_COMPONENT = "component" +FILENAME_DESCRIPTION = "description" +FILENAME_ANALYZER = "analyzer" +FILENAME_RELEASE = "release" +FILENAME_EXECUTABLE = "executable" +FILENAME_REASON = "reason" +FILENAME_COMMENT = "comment" +FILENAME_REPRODUCE = "reproduce" +FILENAME_RATING = "rating" +FILENAME_CMDLINE = "cmdline" +FILENAME_COREDUMP = "coredump" +FILENAME_BACKTRACE = "backtrace" +FILENAME_MEMORYMAP = "memorymap" +FILENAME_KERNELOOPS = "kerneloops" + +CD_DUPHASH = "DUPHASH" +CD_UUID = "UUID" +CD_DUMPDIR = "DumpDir" +CD_COUNT = "Count" +CD_REPORTED = "Reported" +CD_MESSAGE = "Message" + +# FIXME - create method or smth that returns type|editable|content + + class Dump(): """Class for mapping the debug dump to python object""" def __init__(self): self.UUID = None - self.UID = None + self.uid = None self.Count = None - self.Executable = None - self.Package = None - self.Time = None - self.Description = None + self.executable = None + self.package = None + self.time = None + self.description = None self.Message = None self.Reported = None @@ -24,16 +59,16 @@ class Dump(): return self.UUID[CD_CONTENT] def getUID(self): - return self.UID[CD_CONTENT] + return self.uid[CD_CONTENT] def getCount(self): return self.Count[CD_CONTENT] def getExecutable(self): - return self.Executable[CD_CONTENT] + return self.executable[CD_CONTENT] def getPackage(self): - return self.Package[CD_CONTENT] + return self.package[CD_CONTENT] def isReported(self): return self.Reported[CD_CONTENT] == "1" @@ -44,17 +79,17 @@ class Dump(): #return self.Message[CD_CONTENT].split('\n') return self.Message[CD_CONTENT] - def getTime(self,format): + def getTime(self, format): #print format if format: try: - return datetime.fromtimestamp(int(self.Time[CD_CONTENT])).strftime(format) + return datetime.fromtimestamp(int(self.time[CD_CONTENT])).strftime(format) except Exception, e: print e - return int(self.Time[CD_CONTENT]) + return int(self.time[CD_CONTENT]) def getPackageName(self): - return self.Package[CD_CONTENT][:self.Package[CD_CONTENT].find("-")] + return self.package[CD_CONTENT][:self.package[CD_CONTENT].find("-")] def getDescription(self): - return self.Description[CD_CONTENT] + return self.description[CD_CONTENT] diff --git a/src/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py index a8101d4..b7b571d 100644 --- a/src/Gui/CCMainWindow.py +++ b/src/Gui/CCMainWindow.py @@ -25,6 +25,7 @@ from ConfBackend import getCurrentConfBackend, ConfBackendInitError import CCDBusBackend from CC_gui_functions import * from CCDumpList import getDumpList, DumpList +from CCDump import * # FILENAME_xxx, CD_xxx from CCReporterDialog import ReporterDialog from PluginsSettingsDialog import PluginsSettingsDialog from SettingsDialog import SettingsDialog @@ -229,21 +230,29 @@ class MainWindow(): # this should work until we keep the row object in the last position dump = dumpsListStore.get_value(dumpsListStore.get_iter(path[0]), dumpsListStore.get_n_columns()-1) #move this to Dump class + lReported = self.wTree.get_widget("lReported") if dump.isReported(): + report_label_raw = _("This crash has been reported:\n") report_label = _("<b>This crash has been reported:</b>\n") # plugin message follows, but at least in case of kerneloops, # it is not informative (no URL to the report) - for message in dump.getMessage().split('\n'): + for message in dump.getMessage().split(';'): if message: - #Doesn't work (far too easy to make it worse, not better): - #if "http" in message[0:5] or "file:///"[0:8] in message: - # message = "<a href=\"%s\">%s</a>" % (message, message) - report_label += "%s\n" % message + message_clean = message.strip() + if "http" in message_clean[0:5] or "file:///"[0:8] in message_clean: + report_message = "<a href=\"%s\">%s</a>" % (message_clean, message_clean) + else: + report_message = message_clean + report_label += "%s\n" % report_message + report_label_raw += "%s\n" % message_clean log2("setting markup '%s'", report_label) - self.wTree.get_widget("lReported").set_markup(report_label) + lReported.set_text(report_label_raw) + # Sometimes (!) set_markup() fails with + # "GtkWarning: Failed to set text from markup due to error parsing markup: Unknown tag 'a'" + # If it does, then set_text() above acts as a fallback + lReported.set_markup(report_label) else: - self.wTree.get_widget("lReported").set_markup(_("<b>Not reported!</b>")) - lPackage = self.wTree.get_widget("lPackage") + lReported.set_markup(_("<b>Not reported!</b>")) def on_bDelete_clicked(self, button, treeview): dumpsListStore, path = self.dlist.get_selection().get_selected_rows() @@ -301,14 +310,8 @@ class MainWindow(): try: self.pBarWindow.show_all() self.timer = gobject.timeout_add(100, self.progress_update_cb) - # Old way: it needs to talk to daemon - #reporters_settings = {} - ## self.pluginlist = getPluginInfoList(self.ccdaemon, refresh=True) - ## don't force refresh! - #self.pluginlist = getPluginInfoList(self.ccdaemon) - #for plugin in self.pluginlist.getReporterPlugins(): - # reporters_settings[str(plugin)] = plugin.Settings - reporters_settings = getCurrentConfBackend().load_all() + pluginlist = getPluginInfoList(self.ccdaemon) + reporters_settings = pluginlist.getReporterPluginsSettings() log2("Report(result,settings):") log2(" result:%s", str(result)) # Careful, this will print reporters_settings["Password"] too @@ -329,7 +332,7 @@ class MainWindow(): # show the report window with selected report try: - self.ccdaemon.getReport(report["_MWUUID"][2], force=1) + self.ccdaemon.getReport(report[CD_UUID][CD_CONTENT], force=1) except Exception, e: # FIXME #3 dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply # do this async and wait for yum to end with debuginfoinstal diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py index 2cba607..023cc6e 100644 --- a/src/Gui/CCReporterDialog.py +++ b/src/Gui/CCReporterDialog.py @@ -11,16 +11,10 @@ from ABRTPlugin import PluginInfo from PluginSettingsUI import PluginSettingsUI from PluginList import getPluginInfoList #from CCDumpList import getDumpList, DumpList +from CCDump import * # FILENAME_xxx, CD_xxx from abrt_utils import _, log, log1, log2 # FIXME - create method or smth that returns type|editable|content -CD_TYPE = 0 -CD_EDITABLE = 1 -CD_CONTENT = 2 - -CD_SYS = "s" -CD_BIN = "b" -CD_TXT = "t" # response REFRESH = -50 @@ -34,12 +28,11 @@ class ReporterDialog(): self.report = report #Set the Glade file # FIXME add to path - builderfile = "%s%sreport.glade" % (sys.path[0],"/") + builderfile = "%s/report.glade" % sys.path[0] self.builder = gtk.Builder() self.builder.add_from_file(builderfile) #Get the Main Window, and connect the "destroy" event self.window = self.builder.get_object("reporter_dialog") - self.window.set_default_size(640, 480) self.window.connect("response", self.on_response, daemon) if parent: self.window.set_transient_for(parent) @@ -48,24 +41,23 @@ class ReporterDialog(): # comment textview self.tvComment = self.builder.get_object("tvComment") self.tvComment.connect("focus-in-event", self.on_comment_focus_cb) - self.comment_changed = False + self.show_hint_comment = 1 # "how to reproduce" textview self.tevHowToReproduce = self.builder.get_object("tevHowToReproduce") - self.how_to_changed = False - self.builder.get_object("ebErrors").hide() + self.builder.get_object("fErrors").hide() self.builder.get_object("bLog").connect("clicked", self.show_log_cb, log) self.builder.get_object("cbSendBacktrace").connect("toggled", self.on_send_backtrace_toggled) self.allow_send() self.hydrate() - + def check_backtrace(self): print "checking backtrace" - + def warn_user(self, warnings): # FIXME: show in lError - ebErrors = self.builder.get_object("ebErrors") + fErrors = self.builder.get_object("fErrors") lErrors = self.builder.get_object("lErrors") warning_lbl = None for warning in warnings: @@ -74,13 +66,13 @@ class ReporterDialog(): else: warning_lbl = "* %s" % warning lErrors.set_label(warning_lbl) - ebErrors.show_all() - + fErrors.show_all() + def hide_warning(self): - ebErrors = self.builder.get_object("ebErrors") + fErrors = self.builder.get_object("fErrors") lErrors = self.builder.get_object("lErrors") - ebErrors.hide() - + fErrors.hide() + def allow_send(self): self.hide_warning() bSend = self.builder.get_object("bSend") @@ -88,7 +80,7 @@ class ReporterDialog(): send = True error_msgs = [] try: - rating = self.report["rating"] + rating = self.report[FILENAME_RATING] except: rating = None # active buttons acording to required fields @@ -97,31 +89,32 @@ class ReporterDialog(): send = False error_msgs.append(_("You must agree with submitting the backtrace.")) # we have both SendBacktrace and rating - elif rating: + if rating: try: - package = self.report["package"][CD_CONTENT] + package = self.report[FILENAME_PACKAGE][CD_CONTENT] # if we don't have package for some reason except: package = None # not usable report - if int(self.report["rating"][CD_CONTENT]) < 3: + if int(self.report[FILENAME_RATING][CD_CONTENT]) < 3: if package: error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: <b>debuginfo-install %s</b> \nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) else: error_msgs.append(_("The backtrace is unusable, you can't report this!")) # probably usable 3 - elif int(self.report["rating"][CD_CONTENT]) < 4: + elif int(self.report[FILENAME_RATING][CD_CONTENT]) < 4: error_msgs.append(_("The backtrace is incomplete, please make sure you provide good steps to reproduce.")) - + if error_msgs: self.warn_user(error_msgs) bSend.set_sensitive(send) - + def on_send_backtrace_toggled(self, toggle_button): self.allow_send() - + def show_log_cb(self, widget, log): show_log(log, parent=self.window) + # this callback is called when user press Cancel or Report button in Report dialog def on_response(self, dialog, response_id, daemon): # the button has been pressed (probably) @@ -137,9 +130,10 @@ class ReporterDialog(): model[path][3] = not model[path][3] def on_comment_focus_cb(self, widget, event): - if not self.comment_changed: + if self.show_hint_comment: + # clear "hint" text by supplying a fresh, empty TextBuffer widget.set_buffer(gtk.TextBuffer()) - self.comment_changed = True + self.show_hint_comment = 0 def on_config_plugin_clicked(self, button, plugin, image): ui = PluginSettingsUI(plugin, parent=self.window) @@ -201,66 +195,85 @@ class ReporterDialog(): return True return True + def set_label(self, label_widget, text): + if len(text) > label_widget.get_max_width_chars(): + label_widget.set_tooltip_text(text) + label_widget.set_text(text) def hydrate(self): self.editable = [] + self.old_comment = "" + self.old_how_to_reproduce = "" for item in self.report: - if item == "backtrace": + try: + log2("report[%s]:%s/%s/%s", item, self.report[item][0], self.report[item][1], self.report[item][2][0:20]) + except: + pass + + if item == FILENAME_BACKTRACE: buff = gtk.TextBuffer() tvBacktrace = self.builder.get_object("tvBacktrace") buff.set_text(self.report[item][CD_CONTENT]) tvBacktrace.set_buffer(buff) continue - if item == "Comment": - buff = gtk.TextBuffer() - comment = _("Brief description how to reproduce this or what you did...") + + if item == FILENAME_COMMENT: try: if self.report[item][CD_CONTENT]: - comment = self.report[item][CD_CONTENT] - self.comment_changed = True + self.old_comment = self.report[item][CD_CONTENT] except Exception, e: pass - - buff.set_text(comment) - - self.tvComment.set_buffer(buff) continue - if item == "How to reproduce": - buff = gtk.TextBuffer() - how_to_reproduce = _("") + + if item == FILENAME_REPRODUCE: try: if self.report[item][CD_CONTENT]: - how_to_reproduce = self.report[item][CD_CONTENT] - self.how_to_changed = True + self.old_how_to_reproduce = self.report[item][CD_CONTENT] except Exception, e: pass + continue - buff.set_text(how_to_reproduce) + if self.report[item][CD_TYPE] == CD_SYS: + continue - self.tevHowToReproduce.set_buffer(buff) + # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 + # FIXME: handle editable fields + if self.report[item][CD_TYPE] == CD_BIN: + self.builder.get_object("fAttachment").show() + vbAttachments = self.builder.get_object("vbAttachments") + toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) + vbAttachments.pack_start(toggle) + # bind item to checkbox + toggle.item = item + toggle.show() continue - if self.report[item][CD_TYPE] != CD_SYS: - # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 - # FIXME: handle editable fields - if self.report[item][CD_TYPE] == CD_BIN: - self.builder.get_object("fAttachment").show() - vbAttachments = self.builder.get_object("vbAttachments") - toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) - vbAttachments.pack_start(toggle) - # bind item to checkbox - toggle.item = item - toggle.show() - continue - item_label = self.builder.get_object("l%s" % item) - if item_label: - item_label.set_text(self.report[item][CD_CONTENT]) - else: - # no widget to show this item - # probably some new item need to adjust the GUI! - # FIXME: add some window+button to show all the info - # in raw form (smth like the old report dialog) - pass + # It must be CD_TXT field + item_label = self.builder.get_object("l%s" % item) + if item_label: + self.set_label(item_label, self.report[item][CD_CONTENT]) + else: + # no widget to show this item + # probably some new item need to adjust the GUI! + # FIXME: add some window+button to show all the info + # in raw form (smth like the old report dialog) + pass + #end for + + buff = gtk.TextBuffer() + self.show_hint_comment = (self.old_comment == "") + if self.show_hint_comment: + buff.set_text(_("Brief description how to reproduce this or what you did...")) + else: + buff.set_text(self.old_comment) + self.tvComment.set_buffer(buff) + + buff = gtk.TextBuffer() + if self.old_how_to_reproduce == "": + buff.set_text("1.\n2.\n3.\n") + else: + buff.set_text(self.old_how_to_reproduce) + self.tevHowToReproduce.set_buffer(buff) def dehydrate(self): # handle attachments @@ -268,23 +281,22 @@ class ReporterDialog(): for attachment in vbAttachments.get_children(): #print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label()) del self.report[attachment.item] - + # handle comment - if self.comment_changed: - buff = self.tvComment.get_buffer() - self.report["Comment"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] - else: - del self.report["Comment"] + buff = self.tvComment.get_buffer() + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + if self.old_comment != text: + self.report[FILENAME_COMMENT] = [CD_TXT, 'y', text] # handle how to reproduce - if self.how_to_changed: - buff = self.tevHowToReproduce.get_buffer() - self.report["How to reproduce"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] - else: - del self.report["How to reproduce"] + buff = self.tevHowToReproduce.get_buffer() + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + if self.old_how_to_reproduce != text: + self.report[FILENAME_REPRODUCE] = [CD_TXT, 'y', text] #handle backtrace tev_backtrace = self.builder.get_object("tvBacktrace") buff = tev_backtrace.get_buffer() - self.report["backtrace"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + self.report[FILENAME_BACKTRACE] = [CD_TXT, 'y', text] def check_report(self): # FIXME: check the report for passwords and some other potentially @@ -296,4 +308,3 @@ class ReporterDialog(): result = self.window.run() self.window.destroy() return (result, self.report) - diff --git a/src/Gui/CC_gui_functions.py b/src/Gui/CC_gui_functions.py index a9c47fa..e226021 100644 --- a/src/Gui/CC_gui_functions.py +++ b/src/Gui/CC_gui_functions.py @@ -56,9 +56,14 @@ def gui_report_dialog ( report_status_dict, parent_dialog, status_hbox.pack_start(plugin_label, expand=False) status_hbox.pack_start(status_label, expand=False) # 0 means not succesfull - if report_status_dict[plugin][0] == '0': - status_label.set_markup("<span foreground='red'>%s</span>" % report_status_dict[plugin][1]) - elif report_status_dict[plugin][0] == '1': + #if report_status_dict[plugin][0] == '0': + # this first one is actually a fallback to set at least + # a raw text in case when set_markup() fails + status_label.set_text(report_status_dict[plugin][1]) + status_label.set_markup("<span foreground='red'>%s</span>" % report_status_dict[plugin][1]) + # if the report was not succesful then this won't pass so this runs only + # if report succeds and gets overwriten by the status message + if report_status_dict[plugin][0] == '1': if "http" in report_status_dict[plugin][1][0:4] or "file://" in report_status_dict[plugin][1][0:7]: status_label.set_markup("<a href=\"%s\">%s</a>" % (report_status_dict[plugin][1], report_status_dict[plugin][1])) # FIXME: make a new branch for rawhide with gtk 2.17 and remove this diff --git a/src/Gui/PluginList.py b/src/Gui/PluginList.py index d2232bb..82759ae 100644 --- a/src/Gui/PluginList.py +++ b/src/Gui/PluginList.py @@ -38,6 +38,11 @@ class PluginInfoList(list): def getReporterPlugins(self): return [x for x in self if x["Enabled"] == 'yes' and x["Type"] == 'Reporter'] + def getReporterPluginsSettings(self): + reporters_settings = {} + for plugin in self.getReporterPlugins(): + reporters_settings[str(plugin)] = plugin.Settings + return reporters_settings __PFList = None diff --git a/src/Gui/report.glade b/src/Gui/report.glade index d3bf5eb..d6fec06 100644 --- a/src/Gui/report.glade +++ b/src/Gui/report.glade @@ -16,11 +16,12 @@ <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="spacing">5</property> <child> <object class="GtkFrame" id="fSysInfo"> <property name="visible">True</property> <property name="label_xalign">0</property> - <property name="shadow_type">none</property> + <property name="shadow_type">in</property> <child> <object class="GtkAlignment" id="alignment1"> <property name="visible">True</property> @@ -32,6 +33,7 @@ <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="homogeneous">True</property> <child> <object class="GtkLabel" id="l"> <property name="visible">True</property> @@ -78,6 +80,8 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">0</property> </packing> </child> @@ -92,6 +96,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">0</property> @@ -103,6 +108,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">1</property> @@ -114,6 +120,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">2</property> @@ -125,6 +132,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">3</property> @@ -139,6 +147,7 @@ <object class="GtkVBox" id="vbox5"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="homogeneous">True</property> <child> <object class="GtkLabel" id="label4"> <property name="visible">True</property> @@ -185,6 +194,8 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child> @@ -198,6 +209,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">0</property> @@ -209,6 +221,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">1</property> @@ -220,6 +233,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">2</property> @@ -231,6 +245,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">3</property> @@ -245,13 +260,8 @@ </child> </object> </child> - <child type="label"> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="ypad">5</property> - <property name="label" translatable="yes"><b>General information</b></property> - <property name="use_markup">True</property> - </object> + <child type="label_item"> + <placeholder/> </child> </object> <packing> @@ -322,7 +332,7 @@ </packing> </child> <child> - <object class="GtkFrame" id="frame2"> + <object class="GtkFrame" id="fUserInfo"> <property name="visible">True</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> @@ -381,8 +391,6 @@ </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> <property name="position">0</property> </packing> </child> @@ -427,8 +435,6 @@ </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> <property name="position">1</property> </packing> </child> @@ -441,13 +447,8 @@ </child> </object> </child> - <child type="label"> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="ypad">5</property> - <property name="label" translatable="yes"><b>User information</b></property> - <property name="use_markup">True</property> - </object> + <child type="label_item"> + <placeholder/> </child> </object> <packing> @@ -482,75 +483,87 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">3</property> </packing> </child> <child> - <object class="GtkHBox" id="ebErrors"> + <object class="GtkFrame" id="fErrors"> <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">in</property> <child> - <object class="GtkAlignment" id="alignment7"> - <property name="visible">True</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-dialog-warning</property> - <property name="icon-size">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox8"> + <object class="GtkHBox" id="ebErrors"> <property name="visible">True</property> - <property name="orientation">vertical</property> <child> - <object class="GtkLabel" id="label12"> + <object class="GtkAlignment" id="alignment7"> <property name="visible">True</property> - <property name="label" translatable="yes"><b>Please fix the following problems</b></property> - <property name="use_markup">True</property> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">0</property> </packing> </child> <child> - <object class="GtkLabel" id="lErrors"> + <object class="GtkImage" id="image1"> <property name="visible">True</property> - <property name="label" translatable="yes"> </property> - <property name="use_markup">True</property> - <property name="selectable">True</property> + <property name="stock">gtk-dialog-warning</property> + <property name="icon-size">6</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment8"> - <property name="visible">True</property> <child> - <placeholder/> + <object class="GtkVBox" id="vbox8"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Please fix the following problems</b></property> + <property name="use_markup">True</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="lErrors"> + <property name="visible">True</property> + <property name="label" translatable="yes"> </property> + <property name="use_markup">True</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment8"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">3</property> + </packing> </child> </object> - <packing> - <property name="position">3</property> - </packing> + </child> + <child type="label_item"> + <placeholder/> </child> </object> <packing> diff --git a/src/Hooks/abrt-hook-ccpp.cpp b/src/Hooks/abrt-hook-ccpp.cpp index 1c91dc8..b844be7 100644 --- a/src/Hooks/abrt-hook-ccpp.cpp +++ b/src/Hooks/abrt-hook-ccpp.cpp @@ -21,12 +21,10 @@ #include "abrtlib.h" #include "hooklib.h" #include "DebugDump.h" +#include "CrashTypes.h" #include "ABRTException.h" #include <syslog.h> -#define FILENAME_EXECUTABLE "executable" -#define FILENAME_COREDUMP "coredump" - using namespace std; static char* malloc_readlink(const char *linkname) diff --git a/src/Hooks/abrt-hook-python.cpp b/src/Hooks/abrt-hook-python.cpp index c8a25e3..90197cc 100644 --- a/src/Hooks/abrt-hook-python.cpp +++ b/src/Hooks/abrt-hook-python.cpp @@ -26,6 +26,7 @@ #include "abrtlib.h" #include "hooklib.h" #include "DebugDump.h" +#include "CrashTypes.h" #include "ABRTException.h" #if HAVE_CONFIG_H # include <config.h> @@ -149,14 +150,14 @@ int main(int argc, char** argv) dd.SaveText(FILENAME_ANALYZER, "Python"); dd.SaveText(FILENAME_EXECUTABLE, executable); - dd.SaveText("backtrace", bt); + dd.SaveText(FILENAME_BACKTRACE, bt); free(bt); - dd.SaveText("cmdline", cmdline); + dd.SaveText(FILENAME_CMDLINE, cmdline); free(cmdline); - dd.SaveText("uuid", uuid); + dd.SaveText(FILENAME_UUID, uuid); char uid[sizeof(long) * 3 + 2]; sprintf(uid, "%lu", (long)getuid()); - dd.SaveText("uid", uid); + dd.SaveText(FILENAME_UID, uid); dd.Close(); log("saved python crash dump of pid %s to %s", pid, path); diff --git a/src/Hooks/hooklib.cpp b/src/Hooks/hooklib.cpp index 41b9627..06bde97 100644 --- a/src/Hooks/hooklib.cpp +++ b/src/Hooks/hooklib.cpp @@ -47,9 +47,7 @@ void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSi break; } - unsigned len = strlen(line); - if (len > 0 && line[len-1] == '\n') - line[--len] = '\0'; + strchrnul(line, '\n')[0] = '\0'; const char *p = skip_whitespace(line); #undef DIRECTIVE #define DIRECTIVE "MaxCrashReportsSize" |
