[SATYR PATCH] koops: parse taint flags
Martin Milata
mmilata at redhat.com
Mon May 13 13:47:43 UTC 2013
- flag taint_virtual_box was removed because it does not exist (or does
it?), taint_module_gpl removed due to it being the negation of
taint_module_proprietary
- the json format is a bit more compact than was originally intended
Signed-off-by: Martin Milata <mmilata at redhat.com>
---
lib/koops_stacktrace.c | 164 ++++++++++++++++++++------------
lib/koops_stacktrace.h | 2 -
tests/kerneloopses/rhbz-827868-modified | 38 ++++++++
tests/koops_stacktrace.at | 69 ++++++++------
4 files changed, 181 insertions(+), 92 deletions(-)
create mode 100644 tests/kerneloopses/rhbz-827868-modified
diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c
index a10d816..1d68d85 100644
--- a/lib/koops_stacktrace.c
+++ b/lib/koops_stacktrace.c
@@ -24,6 +24,7 @@
#include "strbuf.h"
#include "normalize.h"
#include <string.h>
+#include <stddef.h>
struct sr_koops_stacktrace *
sr_koops_stacktrace_new()
@@ -114,6 +115,67 @@ sr_koops_stacktrace_remove_frame(struct sr_koops_stacktrace *stacktrace,
}
+struct taint_flag {
+ char letter;
+ size_t member_offset;
+};
+
+/* http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/kernel/panic.c?id=HEAD */
+
+#define FLAG_OFFSET(flag) offsetof(struct sr_koops_stacktrace, taint_ ## flag)
+static struct taint_flag flags[] = {
+ { 'P', FLAG_OFFSET(module_proprietary) },
+ { 'F', FLAG_OFFSET(forced_module) },
+ { 'S', FLAG_OFFSET(smp_unsafe) },
+ { 'R', FLAG_OFFSET(forced_removal) },
+ { 'M', FLAG_OFFSET(mce) },
+ { 'B', FLAG_OFFSET(page_release) },
+ { 'U', FLAG_OFFSET(userspace) },
+ { 'D', FLAG_OFFSET(died_recently) },
+ { 'A', FLAG_OFFSET(acpi_overridden) },
+ { 'W', FLAG_OFFSET(warning) },
+ { 'C', FLAG_OFFSET(staging_driver) },
+ { 'I', FLAG_OFFSET(firmware_workaround) },
+ { 'O', FLAG_OFFSET(module_out_of_tree) },
+ { '\0', 0 /* sentinel */ }
+};
+#undef FLAG_OFFSET
+
+/* Based on function kernel_tainted_short from abrt/src/lib/kernel.c */
+static bool
+parse_taint_flags(const char *input, struct sr_koops_stacktrace *stacktrace)
+{
+ /* example of flags: 'Tainted: G B ' */
+ const char *tainted = strstr(input, "Tainted: ");
+ if (!tainted)
+ return false;
+
+ tainted += strlen("Tainted: ");
+
+ for (;;)
+ {
+ if (tainted[0] >= 'A' && tainted[0] <= 'Z')
+ {
+ /* set the appropriate flag */
+ struct taint_flag *f;
+ for (f = flags; f->letter; f++)
+ {
+ if (tainted[0] == f->letter)
+ {
+ *(bool *)((void *)stacktrace + f->member_offset) = true;
+ break;
+ }
+ }
+ }
+ else if (tainted[0] != ' ')
+ break;
+
+ ++tainted;
+ }
+
+ return true;
+}
+
struct sr_koops_stacktrace *
sr_koops_stacktrace_parse(const char **input,
struct sr_location *location)
@@ -122,6 +184,9 @@ sr_koops_stacktrace_parse(const char **input,
struct sr_koops_stacktrace *stacktrace = sr_koops_stacktrace_new();
+ /* Looks for the "Tainted: " line in the whole input */
+ parse_taint_flags(local_input, stacktrace);
+
while (*local_input)
{
struct sr_koops_frame *frame = sr_koops_frame_parse(&local_input);
@@ -185,6 +250,41 @@ sr_koops_stacktrace_parse_modules(const char **input)
return result;
}
+static char *
+taint_flags_to_json(struct sr_koops_stacktrace *stacktrace)
+{
+ struct sr_strbuf *strbuf = sr_strbuf_new();
+
+#define FLAG_APPEND(flag) \
+ if (stacktrace->taint_ ## flag) \
+ sr_strbuf_append_strf(strbuf, ", \"" #flag "\"\n"); \
+
+ FLAG_APPEND(module_proprietary)
+ FLAG_APPEND(forced_module)
+ FLAG_APPEND(forced_removal)
+ FLAG_APPEND(smp_unsafe)
+ FLAG_APPEND(mce)
+ FLAG_APPEND(page_release)
+ FLAG_APPEND(userspace)
+ FLAG_APPEND(died_recently)
+ FLAG_APPEND(acpi_overridden)
+ FLAG_APPEND(warning)
+ FLAG_APPEND(staging_driver)
+ FLAG_APPEND(firmware_workaround)
+ FLAG_APPEND(module_out_of_tree)
+
+#undef FLAG_APPEND
+
+ if (strbuf->len == 0)
+ return sr_strdup("[]");
+
+ sr_strbuf_append_char(strbuf, ']');
+ char *result = sr_strbuf_free_nobuf(strbuf);
+ result[0] = '[';
+ result[strlen(result) - 2] = ' '; /* erase the last newline */
+ return result;
+}
+
char *
sr_koops_stacktrace_to_json(struct sr_koops_stacktrace *stacktrace)
{
@@ -199,65 +299,11 @@ sr_koops_stacktrace_to_json(struct sr_koops_stacktrace *stacktrace)
}
/* Kernel taint flags. */
- sr_strbuf_append_strf(strbuf,
- ", \"taint_module_proprietary\": %s\n",
- stacktrace->taint_module_proprietary ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_module_gpl\": %s\n",
- stacktrace->taint_module_gpl ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_module_out_of_tree\": %s\n",
- stacktrace->taint_module_out_of_tree ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_forced_module\": %s\n",
- stacktrace->taint_forced_module ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_forced_removal\": %s\n",
- stacktrace->taint_forced_removal ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_smp_unsafe\": %s\n",
- stacktrace->taint_smp_unsafe ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_mce\": %s\n",
- stacktrace->taint_mce ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_page_release\": %s\n",
- stacktrace->taint_page_release ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_userspace\": %s\n",
- stacktrace->taint_userspace ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_died_recently\": %s\n",
- stacktrace->taint_died_recently ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_acpi_overridden\": %s\n",
- stacktrace->taint_acpi_overridden ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_warning\": %s\n",
- stacktrace->taint_warning ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_staging_driver\": %s\n",
- stacktrace->taint_staging_driver ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_firmware_workaround\": %s\n",
- stacktrace->taint_firmware_workaround ? "true" : "false");
-
- sr_strbuf_append_strf(strbuf,
- ", \"taint_virtual_box\": %s\n",
- stacktrace->taint_virtual_box ? "true" : "false");
+ char *taint_flags = taint_flags_to_json(stacktrace);
+ char *indented_taint_flags = sr_indent_except_first_line(taint_flags, strlen(", \"taint_flags\": "));
+ free(taint_flags);
+ sr_strbuf_append_strf(strbuf, ", \"taint_flags\": %s\n", indented_taint_flags);
+ free(indented_taint_flags);
/* Modules. */
if (stacktrace->modules)
diff --git a/lib/koops_stacktrace.h b/lib/koops_stacktrace.h
index 62854a8..54bd0cc 100644
--- a/lib/koops_stacktrace.h
+++ b/lib/koops_stacktrace.h
@@ -47,7 +47,6 @@ struct sr_koops_stacktrace
*/
bool taint_module_proprietary;
- bool taint_module_gpl;
bool taint_module_out_of_tree;
bool taint_forced_module;
bool taint_forced_removal;
@@ -62,7 +61,6 @@ struct sr_koops_stacktrace
bool taint_warning;
bool taint_staging_driver;
bool taint_firmware_workaround;
- bool taint_virtual_box;
/**
* @brief List of loaded modules.
diff --git a/tests/kerneloopses/rhbz-827868-modified b/tests/kerneloopses/rhbz-827868-modified
new file mode 100644
index 0000000..c73ef85
--- /dev/null
+++ b/tests/kerneloopses/rhbz-827868-modified
@@ -0,0 +1,38 @@
+[110417.280426] WARNING: at mm/page_alloc.c:2204 __alloc_pages_nodemask+0x231/0x8f0()
+[110417.280429] Hardware name: Latitude E6420
+[110417.280431] Modules linked in: vfat fat usb_storage authenc l2tp_ppp pppox ppp_generic slhc l2tp_netlink l2tp_core rmd160 crypto_null camellia lzo cast6 cast5 deflate zlib_deflate cts gcm ccm serpent_sse2_x86_64 serpent_generic blowfish_generic blowfish_x86_64 blowfish_common twofish_generic twofish_x86_64_3way lrw twofish_x86_64 twofish_common xcbc sha256_generic sha512_generic des_generic ah6 ah4 esp6 esp4 xfrm4_mode_beet xfrm4_tunnel tunnel4 xfrm4_mode_tunnel xfrm4_mode_transport xfrm6_mode_transport xfrm6_mode_ro xfrm6_mode_beet xfrm6_mode_tunnel ipcomp ipcomp6 xfrm_ipcomp xfrm6_tunnel tunnel6 af_key snd_usb_audio snd_usbmidi_lib snd_rawmidi sctp libcrc32c tcp_lp wacom fuse lockd rfcomm bnep snd_hda_codec_hdmi snd_hda_codec_idt binfmt_misc arc4 uvcvideo snd_hda_intel videobuf2_core videodev snd_hda_codec ppdev media dell_wmi videobuf2_vmalloc sparse_keymap videobuf2_memops dell_laptop snd_hwdep snd_seq uinput dcdbas snd_seq_device btusb bluetooth iwlwifi snd_pcm par!
port_pc
+joydev parport snd_timer microcode mac80211 snd soundcore snd_page_alloc i2c_i801 cfg80211 iTCO_wdt iTCO_vendor_support rfkill e1000e sunrpc xts gf128mul dm_crypt sdhci_pci sdhci mmc_core wmi i915 drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: scsi_wait_scan]
+[110417.280525] Pid: 3, comm: ksoftirqd/0 Tainted: P B D O 3.3.7-1.fc16.x86_64 #1
+[110417.280528] Call Trace:
+[110417.280535] [<ffffffff81057adf>] warn_slowpath_common+0x7f/0xc0
+[110417.280539] [<ffffffff81057b3a>] warn_slowpath_null+0x1a/0x20
+[110417.280544] [<ffffffff811296d1>] __alloc_pages_nodemask+0x231/0x8f0
+[110417.280550] [<ffffffff8151fd80>] ? ip_copy_metadata+0x1c0/0x1c0
+[110417.280555] [<ffffffff8151f860>] ? ip_forward_options+0x1f0/0x1f0
+[110417.280559] [<ffffffff81160a93>] alloc_pages_current+0xa3/0x110
+[110417.280563] [<ffffffff81125514>] __get_free_pages+0x14/0x50
+[110417.280569] [<ffffffff8116bb5f>] kmalloc_order_trace+0x3f/0xd0
+[110417.280573] [<ffffffff8116ca87>] __kmalloc+0x177/0x1a0
+[110417.280578] [<ffffffffa0642332>] ? pppol2tp_xmit+0x42/0x220 [l2tp_ppp]
+[110417.280583] [<ffffffff814db0a7>] pskb_expand_head+0x87/0x310
+[110417.280588] [<ffffffff8113dc59>] ? __mod_zone_page_state+0x49/0x50
+[110417.280591] [<ffffffff814da0f5>] ? kfree_skb+0x45/0xc0
+[110417.280595] [<ffffffffa06424dd>] pppol2tp_xmit+0x1ed/0x220 [l2tp_ppp]
+[110417.280600] [<ffffffffa062dd5b>] ppp_push+0x15b/0x650 [ppp_generic]
+[110417.280604] [<ffffffff814db264>] ? pskb_expand_head+0x244/0x310
+[110417.280608] [<ffffffff8112860b>] ? free_compound_page+0x1b/0x20
+[110417.280612] [<ffffffff8112d053>] ? __put_compound_page+0x23/0x30
+[110417.280615] [<ffffffff8112d1d5>] ? put_compound_page+0x125/0x1c0
+[110417.280619] [<ffffffffa062e89f>] ppp_xmit_process+0x46f/0x660 [ppp_generic]
+[110417.280624] [<ffffffffa062ebc8>] ppp_start_xmit+0x138/0x1d0 [ppp_generic]
+[110417.280628] [<ffffffff814e85b2>] dev_hard_start_xmit+0x332/0x6d0
+[110417.280632] [<ffffffff8150447a>] sch_direct_xmit+0xfa/0x1d0
+[110417.280635] [<ffffffff815045f6>] __qdisc_run+0xa6/0x130
+[110417.280639] [<ffffffff814e6883>] net_tx_action+0xe3/0x1f0
+[110417.280643] [<ffffffff8105f0c8>] __do_softirq+0xb8/0x230
+[110417.280646] [<ffffffff8105f2fa>] run_ksoftirqd+0xba/0x170
+[110417.280649] [<ffffffff8105f240>] ? __do_softirq+0x230/0x230
+[110417.280654] [<ffffffff81079da3>] kthread+0x93/0xa0
+[110417.280658] [<ffffffff815fd8e4>] kernel_thread_helper+0x4/0x10
+[110417.280663] [<ffffffff81079d10>] ? kthread_freezable_should_stop+0x70/0x70
+[110417.280666] [<ffffffff815fd8e0>] ? gs_change+0x13/0x13
diff --git a/tests/koops_stacktrace.at b/tests/koops_stacktrace.at
index d30e8b9..b0153bd 100644
--- a/tests/koops_stacktrace.at
+++ b/tests/koops_stacktrace.at
@@ -77,7 +77,8 @@ static void
check(const char *path,
const char *first_function_name,
const char *last_function_name,
- int frame_count)
+ int frame_count,
+ int taint_count)
{
char *error_message;
char *full_input = sr_file_to_string(path, &error_message);
@@ -112,6 +113,23 @@ check(const char *path,
assert(reason);
free(reason);
+ int actual_taint_count =
+ stacktrace->taint_module_proprietary +
+ stacktrace->taint_module_out_of_tree +
+ stacktrace->taint_forced_module +
+ stacktrace->taint_forced_removal +
+ stacktrace->taint_smp_unsafe +
+ stacktrace->taint_mce +
+ stacktrace->taint_page_release +
+ stacktrace->taint_userspace +
+ stacktrace->taint_died_recently +
+ stacktrace->taint_acpi_overridden +
+ stacktrace->taint_warning +
+ stacktrace->taint_staging_driver +
+ stacktrace->taint_firmware_workaround;
+
+ assert(actual_taint_count == taint_count);
+
sr_koops_stacktrace_free(stacktrace);
free(full_input);
}
@@ -119,19 +137,19 @@ check(const char *path,
int
main(void)
{
- check("../../kerneloopses/gitlog-01", "unwind_backtrace", "kthread", 15);
- check("../../kerneloopses/gitlog-02", "unwind_backtrace", "cpu_idle", 27);
- check("../../kerneloopses/gitlog-03", "lockdep_rcu_suspicious", "system_call_fastpath", 19);
- check("../../kerneloopses/gitlog-04", "lockdep_rcu_suspicious", "addrconf_forward_change", 7);
- check("../../kerneloopses/gitlog-05", "mark_held_locks", "sysenter_do_call", 26);
- check("../../kerneloopses/gitlog-06", "lock_acquire", "kernel_thread_helper", 23);
- check("../../kerneloopses/gitlog-07", "__slab_alloc.isra.50.constprop.56", "sysenter_do_call", 14);
- check("../../kerneloopses/gitlog-08", "unwind_backtrace", "sys_write", 13);
+ check("../../kerneloopses/gitlog-01", "unwind_backtrace", "kthread", 15, 0);
+ check("../../kerneloopses/gitlog-02", "unwind_backtrace", "cpu_idle", 27, 0);
+ check("../../kerneloopses/gitlog-03", "lockdep_rcu_suspicious", "system_call_fastpath", 19, 0);
+ check("../../kerneloopses/gitlog-04", "lockdep_rcu_suspicious", "addrconf_forward_change", 7, 0);
+ check("../../kerneloopses/gitlog-05", "mark_held_locks", "sysenter_do_call", 26, 1);
+ check("../../kerneloopses/gitlog-06", "lock_acquire", "kernel_thread_helper", 23, 1);
+ check("../../kerneloopses/gitlog-07", "__slab_alloc.isra.50.constprop.56", "sysenter_do_call", 14, 0);
+ check("../../kerneloopses/gitlog-08", "unwind_backtrace", "sys_write", 13, 1);
- check("../../kerneloopses/gitlog-09", "unwind_backtrace", "cpu_idle", 11);
- check("../../kerneloopses/gitlog-10", NULL, NULL, 0);
- check("../../kerneloopses/gitlog-11", "lockdep_rcu_suspicious", "out_of_memory", 12);
- check("../../kerneloopses/gitlog-12", "unwind_backtrace", "regulator_get_voltage", 6);
+ check("../../kerneloopses/gitlog-09", "unwind_backtrace", "cpu_idle", 11, 1);
+ check("../../kerneloopses/gitlog-10", NULL, NULL, 0, 0);
+ check("../../kerneloopses/gitlog-11", "lockdep_rcu_suspicious", "out_of_memory", 12, 0);
+ check("../../kerneloopses/gitlog-12", "unwind_backtrace", "regulator_get_voltage", 6, 1);
/*
check("../../kerneloopses/gitlog-13", "", "", 0);
check("../../kerneloopses/gitlog-14", "", "", 0);
@@ -154,8 +172,8 @@ main(void)
check("../../kerneloopses/gitlog-31", "", "", 0);
*/
- check("../../kerneloopses/rhbz-827868", "warn_slowpath_common", "gs_change", 32);
- check("../../kerneloopses/rhbz-836206", "__might_sleep", "system_call_fastpath", 23);
+ check("../../kerneloopses/rhbz-827868", "warn_slowpath_common", "gs_change", 32, 0);
+ check("../../kerneloopses/rhbz-836206", "__might_sleep", "system_call_fastpath", 23, 0);
return 0;
}
]])
@@ -175,7 +193,7 @@ int
main(void)
{
char *error_message;
- char *full_input = sr_file_to_string("../../kerneloopses/rhbz-827868",
+ char *full_input = sr_file_to_string("../../kerneloopses/rhbz-827868-modified",
&error_message);
assert(full_input);
@@ -193,21 +211,10 @@ main(void)
char *json = sr_koops_stacktrace_to_json(stacktrace);
puts(json);
assert(0 == strcmp(json,
- "{ \"taint_module_proprietary\": false\n"
- ", \"taint_module_gpl\": false\n"
- ", \"taint_module_out_of_tree\": false\n"
- ", \"taint_forced_module\": false\n"
- ", \"taint_forced_removal\": false\n"
- ", \"taint_smp_unsafe\": false\n"
- ", \"taint_mce\": false\n"
- ", \"taint_page_release\": false\n"
- ", \"taint_userspace\": false\n"
- ", \"taint_died_recently\": false\n"
- ", \"taint_acpi_overridden\": false\n"
- ", \"taint_warning\": false\n"
- ", \"taint_staging_driver\": false\n"
- ", \"taint_firmware_workaround\": false\n"
- ", \"taint_virtual_box\": false\n"
+ "{ \"taint_flags\": [ \"module_proprietary\"\n"
+ " , \"page_release\"\n"
+ " , \"died_recently\"\n"
+ " , \"module_out_of_tree\" ]\n"
", \"modules\":\n"
" [ \"vfat\"\n"
" , \"fat\"\n"
--
1.7.11.7
More information about the Crash-catcher
mailing list