summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-01-06 15:44:41 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2011-01-06 15:44:41 +0100
commitf28b14412ce82bf0787274da87990b06649aa5a5 (patch)
treee566fa54cfba733557449762288d56b5c40052fb /lib
parentc5e7deae4b4835e5e29d9421042f23ec19bbfc86 (diff)
downloadabrt-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.cpp57
-rw-r--r--lib/Utils/Makefile.am1
-rw-r--r--lib/Utils/binhex.cpp74
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;
+}