summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorNikola Pajkovsky <npajkovs@redhat.com>2011-05-31 10:35:51 +0200
committerNikola Pajkovsky <npajkovs@redhat.com>2011-05-31 10:35:51 +0200
commit82c53df6074a4db8f2c5cb4e6b665c2e0881eb28 (patch)
treeb332ff289eaeba6c1ec720f06d0c7cb85eb0550e /src/plugins
parenta2c4ca958c73ee870850f2e51d62f76a1453aaeb (diff)
parent8f350826229717e3bd48dcd6a2f12f6a08b37100 (diff)
downloadabrt-82c53df6074a4db8f2c5cb4e6b665c2e0881eb28.tar.gz
abrt-82c53df6074a4db8f2c5cb4e6b665c2e0881eb28.tar.xz
abrt-82c53df6074a4db8f2c5cb4e6b665c2e0881eb28.zip
Merge branch 'oops/btparser'
* oops/btparser: rhzb#707074 abrt dupe detection needs to ignore some parts of kernel traces
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/abrt-action-analyze-oops.c128
1 files changed, 53 insertions, 75 deletions
diff --git a/src/plugins/abrt-action-analyze-oops.c b/src/plugins/abrt-action-analyze-oops.c
index 02ba3e96..33c65000 100644
--- a/src/plugins/abrt-action-analyze-oops.c
+++ b/src/plugins/abrt-action-analyze-oops.c
@@ -21,10 +21,55 @@
static void hash_oops_str(char hash_str[SHA1_RESULT_LEN*2 + 1], char *oops_buf, const char *oops_ptr)
{
- unsigned char old_c;
- unsigned char c = 0;
+ // Example of call trace part of oops:
+ // Call Trace:
+ // [<f88e11c7>] ? radeon_cp_resume+0x7d/0xbc [radeon]
+ // [<f88745f8>] ? drm_ioctl+0x1b0/0x225 [drm]
+ // [<f88e114a>] ? radeon_cp_resume+0x0/0xbc [radeon]
+ // [<c049b1c0>] ? vfs_ioctl+0x50/0x69
+ // [<c049b414>] ? do_vfs_ioctl+0x23b/0x247
+ // [<c0460a56>] ? audit_syscall_entry+0xf9/0x123
+ // [<c049b460>] ? sys_ioctl+0x40/0x5c
+ // [<c0403c76>] ? syscall_call+0x7/0xb
+ struct strbuf *kernel_bt = strbuf_new();
+ char *call_trace = strstr(oops_buf, "Call Trace");
+ if (call_trace)
+ {
+ call_trace += sizeof("Call Trace\n");
+ char *end_line = strchr(call_trace, '\n');
+ int i = 0;
+ while (end_line)
+ {
+ char *line = xstrndup(call_trace, end_line - call_trace);
+
+ char *p = skip_whitespace(line);
+ char *end_mem_block = strchr(p, ' ');
+ if (!end_mem_block)
+ error_msg_and_die("no [<mem>] mark");
+
+ end_mem_block = skip_whitespace(end_mem_block);
- char *dst = oops_buf;
+ /* +1 for '?' and +1 for space after '?' == +2*/
+ if (end_mem_block && *end_mem_block == '?')
+ end_mem_block += 2;
+
+ /* strip out offset +off/len */
+ char *begin_off_len = strchr(end_mem_block, '+');
+ if (!begin_off_len)
+ error_msg_and_die("no +offset/len at the end of bt");
+
+ char *function = xstrndup(end_mem_block, begin_off_len - end_mem_block);
+ strbuf_append_strf(kernel_bt, "%s\n", function);
+ free(line);
+ if (i == 5)
+ break;
+
+ ++i;
+ call_trace += end_line - call_trace + 1;
+ end_line = strchr(call_trace, '\n');
+ }
+ goto gen_hash;
+ }
/* Special-case: if the first line is of form:
* WARNING: at net/wireless/core.c:614 wdev_cleanup_work+0xe9/0x120 [cfg80211]() (Not tainted)
@@ -39,88 +84,21 @@ static void hash_oops_str(char hash_str[SHA1_RESULT_LEN*2 + 1], char *oops_buf,
p = strchrnul(p + 1, ' '); /* skip function_name+0xNN/0xNNN */
oops_ptr += sizeof("WARNING: at ")-1;
while (oops_ptr < p)
- {
- *dst++ = *oops_ptr++;
- }
- goto gen_hash;
- }
- }
-
- while (1)
- {
- old_c = c;
- c = *oops_ptr++;
- if (!c)
- break;
- if (c == '\n')
- {
- // Exclude some lines which have process name - in some oops classes
- // process name is irrelevant and changes with every oops.
- // Lines we filter out:
- // Pid: 8003, comm: Xorg Not tainted (2.6.27.9-159.fc10.i686 #1)
- // Process Xorg (pid: 8003, ti=f0a0c000 task=f2380000 task.ti=f0a0c000)
- if (strncmp(oops_ptr, "Pid: ", 5) == 0
- || strncmp(oops_ptr, "Process ", 8) == 0
- ) {
- while (*oops_ptr && *oops_ptr != '\n')
- oops_ptr++;
- continue;
- }
- }
- if (!isalnum(old_c))
- {
- if (c >= '0' && c <= '9')
- {
- // Convert all (possibly hex) numbers to just one '0'
- if (c == '0' && *oops_ptr == 'x') // "0xSOMETHING"
- oops_ptr++;
- while (isxdigit(*oops_ptr))
- oops_ptr++;
- c = '0';
- }
- else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
- {
- // This *may be* a hex number without 0x prefix: "f0a0c000"
- // Check that it indeed is, and replace with '0'
- const char *oops_ptr2 = oops_ptr;
- while (isxdigit(*oops_ptr2))
- oops_ptr2++;
- // Does it end in a letter which is not a hex digit?
- // (Example: "abcw" is not a hex number, "abc " is)
- if (!isalpha(*oops_ptr2))
- {
- // It's "abc " case. Skip the "abc" string
- oops_ptr = oops_ptr2;
- c = '0';
- }
- // else: hash the string as-is
- }
+ strbuf_append_char(kernel_bt, *oops_ptr++);
}
- // TODO: Drop call trace tail - in interrupt-driven oopses,
- // everything before interrupt is irrelevant.
- // Example of call trace part of oops:
- // Call Trace:
- // [<f88e11c7>] ? radeon_cp_resume+0x7d/0xbc [radeon]
- // [<f88745f8>] ? drm_ioctl+0x1b0/0x225 [drm]
- // [<f88e114a>] ? radeon_cp_resume+0x0/0xbc [radeon]
- // [<c049b1c0>] ? vfs_ioctl+0x50/0x69
- // [<c049b414>] ? do_vfs_ioctl+0x23b/0x247
- // [<c0460a56>] ? audit_syscall_entry+0xf9/0x123
- // [<c049b460>] ? sys_ioctl+0x40/0x5c
- // [<c0403c76>] ? syscall_call+0x7/0xb
-
- *dst++ = c;
}
- gen_hash: ;
+gen_hash: ;
char hash_bytes[SHA1_RESULT_LEN];
sha1_ctx_t sha1ctx;
sha1_begin(&sha1ctx);
- sha1_hash(&sha1ctx, oops_buf, dst - oops_buf);
+ sha1_hash(&sha1ctx, kernel_bt->buf, kernel_bt->len);
sha1_end(&sha1ctx, hash_bytes);
+ strbuf_free(kernel_bt);
bin2hex(hash_str, hash_bytes, SHA1_RESULT_LEN)[0] = '\0';
+ VERB3 log("hash: %s", hash_str);
}
int main(int argc, char **argv)