diff options
-rw-r--r-- | abrt.spec | 1 | ||||
-rw-r--r-- | inc/crash_types.h | 2 | ||||
-rw-r--r-- | lib/plugins/Python.cpp | 91 | ||||
-rw-r--r-- | src/daemon/Makefile.am | 19 | ||||
-rw-r--r-- | src/daemon/abrt-action-analyze-python.c | 119 |
5 files changed, 183 insertions, 49 deletions
@@ -350,6 +350,7 @@ fi %{_sbindir}/abrtd %{_sbindir}/abrt-server %{_sbindir}/abrt-action-analyze-c +%{_sbindir}/abrt-action-analyze-python %{_sbindir}/abrt-action-generate-backtrace %{_sbindir}/abrt-action-save-package-data %{_bindir}/abrt-action-bugzilla diff --git a/inc/crash_types.h b/inc/crash_types.h index 8185edf4..d425f690 100644 --- a/inc/crash_types.h +++ b/inc/crash_types.h @@ -63,7 +63,7 @@ // CD_UID from _somewhere_ in order to be able to store it in DB record, // right?) #define CD_UID "uid" -/* CCpp is converted to save uuid as a file (python and oops aren't yet): */ +/* CCpp and Python are converted to save uuid as a file (oops isn't yet): */ #define CD_UUID "uuid" #define CD_INFORMALL "InformAll" #define CD_DUMPDIR "DumpDir" diff --git a/lib/plugins/Python.cpp b/lib/plugins/Python.cpp index ea3e1ade..eae1cdf1 100644 --- a/lib/plugins/Python.cpp +++ b/lib/plugins/Python.cpp @@ -22,66 +22,61 @@ using namespace std; -string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) +static string load(const char *dirname, const char *filename) { - struct dump_dir *dd = dd_opendir(pDebugDumpDir, /*flags:*/ 0); - if (!dd) - return string(""); + string ret; - char *bt = dd_load_text(dd, FILENAME_BACKTRACE); + struct dump_dir *dd = dd_opendir(dirname, /*flags:*/ 0); + if (!dd) + return ret; /* "" */ + char *s = dd_load_text(dd, filename); dd_close(dd); - const char *bt_end = strchrnul(bt, '\n'); - - char hash_str[MD5_RESULT_LEN*2 + 1]; - unsigned char hash2[MD5_RESULT_LEN]; - md5_ctx_t md5ctx; - md5_begin(&md5ctx); - // Better: - // "example.py:1:<module>:ZeroDivisionError: integer division or modulo by zero" - //md5_hash(bt_str, bt_end - bt_str, &md5ctx); - // For now using compat version: + if (!s[0]) { - char *copy = xstrndup(bt, bt_end - bt); - free(bt); - char *s = copy; - char *d = copy; - unsigned colon_cnt = 0; - while (*s && colon_cnt < 3) + free(s); + + pid_t pid = fork(); + if (pid < 0) { - if (*s != ':') - *d++ = *s; - else - colon_cnt++; - s++; + perror_msg("fork"); + return ret; /* "" */ } - // "example.py1<module>" - md5_hash(copy, d - copy, &md5ctx); -//*d = '\0'; log("str:'%s'", copy); - free(copy); - } - md5_end(hash2, &md5ctx); - - // Hash is MD5_RESULT_LEN bytes long, but we use only first 4 - // (I don't know why old Python code was using only 4, I mimic that) - unsigned len = 4; - char *d = hash_str; - unsigned char *s = hash2; - while (len) - { - *d++ = "0123456789abcdef"[*s >> 4]; - *d++ = "0123456789abcdef"[*s & 0xf]; - s++; - len--; + if (pid == 0) /* child */ + { + char *argv[4]; /* abrt-action-analyze-python -d DIR <NULL> */ + char **pp = argv; + *pp++ = (char*)"abrt-action-analyze-python"; + *pp++ = (char*)"-d"; + *pp++ = (char*)dirname; + *pp = NULL; + + execvp(argv[0], argv); + perror_msg_and_die("Can't execute '%s'", argv[0]); + } + /* parent */ + waitpid(pid, NULL, 0); + + dd = dd_opendir(dirname, /*flags:*/ 0); + if (!dd) + return ret; /* "" */ + s = dd_load_text(dd, filename); + dd_close(dd); } - *d = '\0'; -//log("hash2:%s str:'%.*s'", hash_str, (int)(bt_end - bt_str), bt_str); - return hash_str; + ret = s; + free(s); + return ret; +} + +string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) +{ + return load(pDebugDumpDir, CD_UUID); } + string CAnalyzerPython::GetGlobalUUID(const char *pDebugDumpDir) { - return GetLocalUUID(pDebugDumpDir); + return load(pDebugDumpDir, FILENAME_DUPHASH); } void CAnalyzerPython::Init() diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 3d307128..dd9351ee 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -5,6 +5,7 @@ bin_SCRIPTS = \ sbin_PROGRAMS = abrtd \ abrt-server \ abrt-action-analyze-c \ + abrt-action-analyze-python \ abrt-action-generate-backtrace \ abrt-action-save-package-data @@ -77,6 +78,24 @@ abrt_action_analyze_c_CPPFLAGS = \ abrt_action_analyze_c_LDADD = \ ../../lib/utils/libABRTUtils.la +abrt_action_analyze_python_SOURCES = \ + abrt-action-analyze-python.c +abrt_action_analyze_python_CPPFLAGS = \ + -I$(srcdir)/../../inc \ + -I$(srcdir)/../../lib/utils \ + -DBIN_DIR=\"$(bindir)\" \ + -DVAR_RUN=\"$(VAR_RUN)\" \ + -DCONF_DIR=\"$(CONF_DIR)\" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ + -DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + -D_GNU_SOURCE \ + -Wall -Werror +abrt_action_analyze_python_LDADD = \ + ../../lib/utils/libABRTUtils.la + abrt_action_generate_backtrace_SOURCES = \ abrt-action-generate-backtrace.c abrt_action_generate_backtrace_CPPFLAGS = \ diff --git a/src/daemon/abrt-action-analyze-python.c b/src/daemon/abrt-action-analyze-python.c new file mode 100644 index 00000000..72eb4a28 --- /dev/null +++ b/src/daemon/abrt-action-analyze-python.c @@ -0,0 +1,119 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "abrtlib.h" +#include "parse_options.h" + +#define PROGNAME "abrt-action-analyze-python" + +// Hash is MD5_RESULT_LEN bytes long, but we use only first 4 +// (I don't know why old Python code was using only 4, I mimic that) +#define HASH_STRING_HEX_DIGITS 4 + +int main(int argc, char **argv) +{ + char *env_verbose = getenv("ABRT_VERBOSE"); + if (env_verbose) + g_verbose = atoi(env_verbose); + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + PROGNAME" [-vs] -d DIR\n\n" + "Calculates and saves UUID and DUPHASH of python crash dumps" + ); + const char *dump_dir_name = "."; + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_s = 1 << 2, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR", _("Crash dump directory")), + OPT_BOOL( 's', NULL, NULL, _("Log to syslog" )), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); + +//Maybe we will want this... later +// msg_prefix = xasprintf(PROGNAME"[%u]", getpid()); +// if (opts & OPT_s) +// { +// openlog(msg_prefix, 0, LOG_DAEMON); +// logmode = LOGMODE_SYSLOG; +// } + + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (!dd) + return 1; + char *bt = dd_load_text(dd, FILENAME_BACKTRACE); + + /* Hash 1st line of backtrace and save it as UUID and DUPHASH */ + + const char *bt_end = strchrnul(bt, '\n'); + unsigned char hash_bytes[MD5_RESULT_LEN]; + md5_ctx_t md5ctx; + md5_begin(&md5ctx); + // Better: + // "example.py:1:<module>:ZeroDivisionError: integer division or modulo by zero" + //md5_hash(bt_str, bt_end - bt_str, &md5ctx); + //free(bt); + // For now using compat version: + { + char *copy = xstrndup(bt, bt_end - bt); + free(bt); + char *s = copy; + char *d = copy; + unsigned colon_cnt = 0; + while (*s && colon_cnt < 3) + { + if (*s != ':') + *d++ = *s; + else + colon_cnt++; + s++; + } + // copy = "example.py1<module>" + md5_hash(copy, d - copy, &md5ctx); + free(copy); + } + // end of compat version + md5_end(hash_bytes, &md5ctx); + + char hash_str[HASH_STRING_HEX_DIGITS*2 + 1]; + unsigned len = HASH_STRING_HEX_DIGITS; + char *d = hash_str; + unsigned char *s = hash_bytes; + while (len) + { + *d++ = "0123456789abcdef"[*s >> 4]; + *d++ = "0123456789abcdef"[*s & 0xf]; + s++; + len--; + } + *d = '\0'; + + dd_save_text(dd, CD_UUID, hash_str); + dd_save_text(dd, FILENAME_DUPHASH, hash_str); + dd_close(dd); + + return 0; +} |