diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2011-01-06 15:44:41 +0100 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2011-01-06 15:44:41 +0100 |
commit | f28b14412ce82bf0787274da87990b06649aa5a5 (patch) | |
tree | e566fa54cfba733557449762288d56b5c40052fb /lib | |
parent | c5e7deae4b4835e5e29d9421042f23ec19bbfc86 (diff) | |
download | abrt-f28b14412ce82bf0787274da87990b06649aa5a5.tar.gz abrt-f28b14412ce82bf0787274da87990b06649aa5a5.tar.xz abrt-f28b14412ce82bf0787274da87990b06649aa5a5.zip |
pass old pattern to ccpp hook and use it
abrtd:
instead of
"|/usr/libexec/abrt-ccpp-hook DEBUG_DUMPS_DIR %p %s %u %c",
sets coredump handler to
"|/usr/libexec/abrt-ccpp-hook DEBUG_DUMPS_DIR %s %c %p %u %g %t %h %e OLD_PATTERN"
abrt-ccpp-hook:
expands OLD_PATTERN using values of %s %c %p %u %g %t %h %e
and uses it as a name of "compat coredump".
Patch has a feature which prevents usage of kernel-truncated
OLD_PATTERN: it is passed as hex string *with terminating NUL*
(encoded as 00). If ccpp hook doesn't see 00, it refuses to use
OLD_PATTERN and uses string "core" instead.
Run tested. On a new kernel, passes up to 27 char long old pattern.
Longer patterns are still truncated.
This may be improved in future kernels.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Plugins/CCpp.cpp | 57 | ||||
-rw-r--r-- | lib/Utils/Makefile.am | 1 | ||||
-rw-r--r-- | lib/Utils/binhex.cpp | 74 |
3 files changed, 120 insertions, 12 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 3dbd73e1..b028c416 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -39,15 +39,27 @@ using namespace std; #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" -#define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u %c" +/* + * %s - signal number + * %c - ulimit -c value + * %p - pid + * %u - uid + * %g - gid + * %t - UNIX time of dump + * %h - hostname + * %e - executable filename + * %% - output one "%" + */ +#define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %s %c %p %u %g %t %h %e" + #define CORE_PIPE_LIMIT_IFACE "/proc/sys/kernel/core_pipe_limit" /* core_pipe_limit specifies how many dump_helpers might run at the same time -0 - means unlimited, but the it's not guaranteed that /proc/<pid> of crashing -process might not be available for dump_helper -4 - means that 4 dump_helpers can run at the same time, which should be enough -for ABRT, we can miss some crashes, but what are the odds that more processes -crash at the same time? This value has been recommended by nhorman -*/ + * 0 - means unlimited, but the it's not guaranteed that /proc/<pid> + * of crashing process will be available for dump_helper + * 4 - means that 4 dump_helpers can run at the same time, which should be enough + * for ABRT, we can miss some crashes, but what are the odds that more processes + * crash at the same time? This value has been recommended by nhorman + */ #define CORE_PIPE_LIMIT "4" #define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di" @@ -796,7 +808,7 @@ void CAnalyzerCCpp::Init() } if (m_sOldCorePattern[0] == '|') { - if (m_sOldCorePattern == CORE_PATTERN) + if (strncmp(m_sOldCorePattern.c_str(), CORE_PATTERN, strlen(CORE_PATTERN)) == 0) { log("warning: %s already contains %s, " "did abrt daemon crash recently?", @@ -820,14 +832,35 @@ void CAnalyzerCCpp::Init() fp = fopen(CORE_PATTERN_IFACE, "w"); if (fp) { - fputs(CORE_PATTERN, fp); + if (m_sOldCorePattern[0] != '|') + { + const char *old = m_sOldCorePattern.c_str(); + unsigned len = strchrnul(old, '\n') - old; + char *hex_old = (char*)xmalloc(len * 2 + 1); + bin2hex(hex_old, old, len)[0] = '\0'; + /* Trailing 00 is a sentinel. Decoder in the hook will check it. + * If it won't see it, then kernel has truncated the argument: + */ + char *pattern = xasprintf("%s %s00", CORE_PATTERN, hex_old); + //log("old:'%s'->'%s'", old, hex_old); + //log("pattern:'%s'", pattern); + + fputs(pattern, fp); + + free(pattern); + free(hex_old); + } + else + { + fputs(CORE_PATTERN, fp); + } fclose(fp); } /* read the core_pipe_limit and change it if it's == 0 - otherwise the abrt-hook-ccpp won't be able to read /proc/<pid> - of the crashing process - */ + * otherwise the abrt-hook-ccpp won't be able to read /proc/<pid> + * of the crashing process + */ fp = fopen(CORE_PIPE_LIMIT_IFACE, "r"); if (fp) { diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index b22e1177..12829b90 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -12,6 +12,7 @@ AM_YFLAGS = --verbose libABRTUtils_la_SOURCES = \ xfuncs.cpp \ encbase64.cpp \ + binhex.cpp \ stdio_helpers.cpp \ read_write.cpp \ logging.cpp \ diff --git a/lib/Utils/binhex.cpp b/lib/Utils/binhex.cpp new file mode 100644 index 00000000..1fcb7445 --- /dev/null +++ b/lib/Utils/binhex.cpp @@ -0,0 +1,74 @@ +/* + 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 version 2 + as published by the Free Software Foundation. + + 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" + +static const char hexdigits_locase[] = "0123456789abcdef"; + +/* Emit a string of hex representation of bytes */ +char *bin2hex(char *dst, const char *str, int count) +{ + while (count) { + unsigned char c = *str++; + /* put lowercase hex digits */ + *dst++ = hexdigits_locase[c >> 4]; + *dst++ = hexdigits_locase[c & 0xf]; + count--; + } + return dst; +} + +/* Convert "xxxxxxxx" hex string to binary, no more than COUNT bytes */ +char *hex2bin(char *dst, const char *str, int count) +{ + /* Parts commented out with // allow parsing + * of strings like "xx:x:x:xx:xx:xx:xxxxxx" + * (IPv6, ethernet addresses and the like). + */ + errno = EINVAL; + while (*str && count) { + uint8_t val; + uint8_t c; + + c = *str++; + if (isdigit(c)) + val = c - '0'; + else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') + val = (c|0x20) - ('a' - 10); + else + return NULL; + val <<= 4; + c = *str; + if (isdigit(c)) + val |= c - '0'; + else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') + val |= (c|0x20) - ('a' - 10); + //else if (c == ':' || c == '\0') + // val >>= 4; + else + return NULL; + + *dst++ = val; + //if (c != '\0') + str++; + //if (*str == ':') + // str++; + count--; + } + errno = (*str ? ERANGE : 0); + return dst; +} |