From 3a16d6494d6117c7515ad9000b1f9d86a54bb536 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 Jan 2011 16:49:30 +0100 Subject: remove dumpoops and KerneloopsScanner plugin Signed-off-by: Denys Vlasenko --- src/plugins/KerneloopsSysLog.c | 391 ----------------------------------------- 1 file changed, 391 deletions(-) delete mode 100644 src/plugins/KerneloopsSysLog.c (limited to 'src/plugins/KerneloopsSysLog.c') diff --git a/src/plugins/KerneloopsSysLog.c b/src/plugins/KerneloopsSysLog.c deleted file mode 100644 index 162fd977..00000000 --- a/src/plugins/KerneloopsSysLog.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - 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. - - Authors: - Anton Arapov - Arjan van de Ven - */ -#include "abrtlib.h" -#include "KerneloopsSysLog.h" -#include - -static void queue_oops(GList **vec, const char *data, const char *version) -{ - char *ver_data = xasprintf("%s\n%s", version, data); - *vec = g_list_append(*vec, ver_data); -} - -/* - * extract_version tries to find the kernel version in given data - */ -static char *extract_version(const char *linepointer) -{ - if (strstr(linepointer, "Pid") - || strstr(linepointer, "comm") - || strstr(linepointer, "CPU") - || strstr(linepointer, "REGS") - || strstr(linepointer, "EFLAGS") - ) { - char* start; - char* end; - - start = strstr((char*)linepointer, "2.6."); - if (start) - { - end = strchr(start, ')'); - if (!end) - end = strchrnul(start, ' '); - return xstrndup(start, end-start); - } - } - - return NULL; -} - -/* - * extract_oops tries to find oops signatures in a log - */ -struct line_info { - char *ptr; - char level; -}; - -static int record_oops(GList **oopses, struct line_info* lines_info, int oopsstart, int oopsend) -{ - int q; - int len; - char *oops; - char *version; - - len = 2; - for (q = oopsstart; q <= oopsend; q++) - len += strlen(lines_info[q].ptr) + 1; - - oops = (char*)xzalloc(len); - - version = NULL; - for (q = oopsstart; q <= oopsend; q++) - { - if (!version) - version = extract_version(lines_info[q].ptr); - - if (lines_info[q].ptr[0]) - { - strcat(oops, lines_info[q].ptr); - strcat(oops, "\n"); - } - } - int rv = 1; - /* too short oopses are invalid */ - if (strlen(oops) > 100) - queue_oops(oopses, oops, version ? version : "undefined"); - else - { - VERB3 log("Dropped oops: too short"); - rv = 0; - } - free(oops); - free(version); - return rv; -} -#define REALLOC_CHUNK 1000 -int extract_oopses(GList **oopses, char *buffer, size_t buflen) -{ - char *c; - int linecount = 0; - int lines_info_alloc = 0; - struct line_info *lines_info = NULL; - - /* Split buffer into lines */ - - if (buflen != 0) - buffer[buflen - 1] = '\n'; /* the buffer usually ends with \n, but let's make sure */ - c = buffer; - while (c < buffer + buflen) - { - char linelevel; - char *c9; - char *colon; - - c9 = (char*)memchr(c, '\n', buffer + buflen - c); /* a \n will always be found */ - assert(c9); - *c9 = '\0'; /* turn the \n into a string termination */ - if (c9 == c) - goto next_line; - - /* Is it a syslog file (/var/log/messages or similar)? - * Even though _usually_ it looks like "Nov 19 12:34:38 localhost kernel: xxx", - * some users run syslog in non-C locale: - * "2010-02-22T09:24:08.156534-08:00 gnu-4 gnome-session[2048]: blah blah" - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !!! - * We detect it by checking for N:NN:NN pattern in first 15 chars - * (and this still is not good enough... false positive: "pci 0000:15:00.0: PME# disabled") - */ - colon = strchr(c, ':'); - if (colon && colon > c && colon < c + 15 - && isdigit(colon[-1]) /* N:... */ - && isdigit(colon[1]) /* ...N:NN:... */ - && isdigit(colon[2]) - && colon[3] == ':' - && isdigit(colon[4]) /* ...N:NN:NN... */ - && isdigit(colon[5]) - ) { - /* It's syslog file, not a bare dmesg */ - - /* Skip non-kernel lines */ - char *kernel_str = strstr(c, "kernel: "); - if (kernel_str == NULL) - { - /* if we see our own marker: - * "hostname abrt: Kerneloops: Reported 1 kernel oopses to Abrt" - * we know we submitted everything upto here already */ - if (strstr(c, "abrt:") && strstr(c, "Abrt")) - { - VERB3 log("Found our marker at line %d, restarting line count from 0", linecount); - linecount = 0; - lines_info_alloc = 0; - free(lines_info); - lines_info = NULL; - } - goto next_line; - } - c = kernel_str + sizeof("kernel: ")-1; - } - - linelevel = 0; - /* store and remove kernel log level */ - if (*c == '<' && c[1] && c[2] == '>') - { - linelevel = c[1]; - c += 3; - } - /* remove jiffies time stamp counter if present */ - if (*c == '[') - { - char *c2 = strchr(c, '.'); - char *c3 = strchr(c, ']'); - if (c2 && c3 && (c2 < c3) && (c3-c) < 14 && (c2-c) < 8) - { - c = c3 + 1; - if (*c == ' ') - c++; - } - } - if (linecount >= lines_info_alloc) - { - lines_info_alloc += REALLOC_CHUNK; - lines_info = (struct line_info*)xrealloc(lines_info, - lines_info_alloc * sizeof(lines_info[0])); - } - lines_info[linecount].ptr = c; - lines_info[linecount].level = linelevel; - linecount++; -next_line: - c = c9 + 1; - } - - /* Analyze lines */ - - int i; - char prevlevel = 0; - int oopsstart = -1; - int inbacktrace = 0; - int oopsesfound = 0; - - i = 0; - while (i < linecount) - { - char *curline = lines_info[i].ptr; - - if (curline == NULL) - { - i++; - continue; - } - while (*curline == ' ') - curline++; - - if (oopsstart < 0) - { - /* Find start-of-oops markers */ - /* In some comparisons, we skip 1st letter, to avoid dealing with - * changes in capitalization in kernel. For example, I see that - * current kernel git (at 2011-01-01) has both "kernel BUG at ..." - * and "Kernel BUG at ..." messages, and I don't want to change - * the code below whenever kernel is changed to use "K" (or "k") - * uniformly. - */ - if (strstr(curline, /*g*/ "eneral protection fault:")) - oopsstart = i; - else if (strstr(curline, "BUG:")) - oopsstart = i; - else if (strstr(curline, /*k*/ "ernel BUG at")) - oopsstart = i; - else if (strstr(curline, "do_IRQ: stack overflow:")) - oopsstart = i; - else if (strstr(curline, "RTNL: assertion failed")) - oopsstart = i; - else if (strstr(curline, /*e*/ "eek! page_mapcount(page) went negative!")) - oopsstart = i; - else if (strstr(curline, /*n*/ "ear stack overflow (cur:")) - oopsstart = i; - else if (strstr(curline, /*d*/ "ouble fault:")) - oopsstart = i; - else if (strstr(curline, /*b*/ "adness at")) - oopsstart = i; - else if (strstr(curline, "NETDEV WATCHDOG")) - oopsstart = i; - else if (strstr(curline, "WARNING: at ")) /* WARN_ON() generated message */ - oopsstart = i; - else if (strstr(curline, /*u*/ "nable to handle kernel")) - oopsstart = i; - else if (strstr(curline, /*s*/ "ysctl table check failed")) - oopsstart = i; - else if (strstr(curline, "INFO: possible recursive locking detected")) - oopsstart = i; - // Not needed: "--[ cut here ]--" is always followed - // by "Badness at", "kernel BUG at", or "WARNING: at" string - //else if (strstr(curline, "------------[ cut here ]------------")) - // oopsstart = i; - else if (strstr(curline, "list_del corruption")) - oopsstart = i; - else if (strstr(curline, "list_add corruption")) - oopsstart = i; - - if (i >= 3 && strstr(curline, "Oops:")) - oopsstart = i-3; - - if (oopsstart >= 0) - { - /* debug information */ - VERB3 { - log("Found oops at line %d: '%s'", oopsstart, lines_info[oopsstart].ptr); - if (oopsstart != i) - log("Trigger line is %d: '%s'", i, c); - } - /* try to find the end marker */ - int i2 = i + 1; - while (i2 < linecount && i2 < (i+50)) - { - if (strstr(lines_info[i2].ptr, "---[ end trace")) - { - inbacktrace = 1; - i = i2; - break; - } - i2++; - } - } - } - - /* Are we entering a call trace part? */ - /* a call trace starts with "Call Trace:" or with the " [<.......>] function+0xFF/0xAA" pattern */ - if (oopsstart >= 0 && !inbacktrace) - { - if (strstr(curline, "Call Trace:")) - inbacktrace = 1; - else - if (strnlen(curline, 9) > 8 - && curline[0] == '[' && curline[1] == '<' - && strstr(curline, ">]") - && strstr(curline, "+0x") - && strstr(curline, "/0x") - ) { - inbacktrace = 1; - } - } - - /* Are we at the end of an oops? */ - else if (oopsstart >= 0 && inbacktrace) - { - int oopsend = INT_MAX; - - /* line needs to start with " [" or have "] [" if it is still a call trace */ - /* example: "[] radeon_get_ring_head+0x16/0x41 [radeon]" */ - if (curline[0] != '[' - && !strstr(curline, "] [") - && !strstr(curline, "--- Exception") - && !strstr(curline, "LR =") - && !strstr(curline, "<#DF>") - && !strstr(curline, "") - && !strstr(curline, "") - && !strstr(curline, "<>") - && strncmp(curline, "Code: ", 6) != 0 - && strncmp(curline, "RIP ", 4) != 0 - && strncmp(curline, "RSP ", 4) != 0 - ) { - oopsend = i-1; /* not a call trace line */ - } - /* oops lines are always more than 8 chars long */ - else if (strnlen(curline, 8) < 8) - oopsend = i-1; - /* single oopses are of the same loglevel */ - else if (lines_info[i].level != prevlevel) - oopsend = i-1; - else if (strstr(curline, "Instruction dump:")) - oopsend = i; - /* if a new oops starts, this one has ended */ - else if (strstr(curline, "WARNING: at ") && oopsstart != i) /* WARN_ON() generated message */ - oopsend = i-1; - else if (strstr(curline, "Unable to handle") && oopsstart != i) - oopsend = i-1; - /* kernel end-of-oops marker (not including marker itself) */ - else if (strstr(curline, "---[ end trace")) - oopsend = i-1; - - if (oopsend <= i) - { - VERB3 log("End of oops at line %d (%d): '%s'", oopsend, i, lines_info[oopsend].ptr); - if (record_oops(oopses, lines_info, oopsstart, oopsend)) - oopsesfound++; - oopsstart = -1; - inbacktrace = 0; - } - } - - prevlevel = lines_info[i].level; - i++; - - if (oopsstart >= 0) - { - /* Do we have a suspiciously long oops? Cancel it */ - if (i-oopsstart > 60) - { - inbacktrace = 0; - oopsstart = -1; - VERB3 log("Dropped oops, too long"); - continue; - } - if (!inbacktrace && i-oopsstart > 40) - { - /*inbacktrace = 0; - already is */ - oopsstart = -1; - VERB3 log("Dropped oops, too long"); - continue; - } - } - } /* while (i < linecount) */ - - /* process last oops if we have one */ - if (oopsstart >= 0 && inbacktrace) - { - int oopsend = i-1; - VERB3 log("End of oops at line %d (end of file): '%s'", oopsend, lines_info[oopsend].ptr); - if (record_oops(oopses, lines_info, oopsstart, oopsend)) - oopsesfound++; - } - - free(lines_info); - return oopsesfound; -} -- cgit