--- lib/Makefile.am | 1 + lib/Makefile.in | 12 ++++++++- lib/normalize.h | 7 +++++ lib/normalize_oops.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/normalize.at | 49 +++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 lib/normalize_oops.c
diff --git a/lib/Makefile.am b/lib/Makefile.am index 4fba7f4..b66c69d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,6 +36,7 @@ libbtparser_la_SOURCES = \ normalize_libstdcpp.c \ normalize_linux.c \ normalize_xorg.c \ + normalize_oops.c \ sharedlib.c \ strbuf.c \ thread.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in index fdf2888..290859e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -95,7 +95,8 @@ am_libbtparser_la_OBJECTS = $(am__objects_1) \ libbtparser_la-normalize_gtk.lo \ libbtparser_la-normalize_libstdcpp.lo \ libbtparser_la-normalize_linux.lo \ - libbtparser_la-normalize_xorg.lo libbtparser_la-sharedlib.lo \ + libbtparser_la-normalize_xorg.lo \ + libbtparser_la-normalize_oops.lo libbtparser_la-sharedlib.lo \ libbtparser_la-strbuf.lo libbtparser_la-thread.lo \ libbtparser_la-utils.lo libbtparser_la_OBJECTS = $(am_libbtparser_la_OBJECTS) @@ -291,6 +292,7 @@ libbtparser_la_SOURCES = \ normalize_libstdcpp.c \ normalize_linux.c \ normalize_xorg.c \ + normalize_oops.c \ sharedlib.c \ strbuf.c \ thread.c \ @@ -398,6 +400,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-normalize_gtk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-normalize_libstdcpp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-normalize_linux.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-normalize_oops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-normalize_xorg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-sharedlib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbtparser_la-strbuf.Plo@am__quote@ @@ -558,6 +561,13 @@ libbtparser_la-normalize_xorg.lo: normalize_xorg.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbtparser_la_CFLAGS) $(CFLAGS) -c -o libbtparser_la-normalize_xorg.lo `test -f 'normalize_xorg.c' || echo '$(srcdir)/'`normalize_xorg.c
+libbtparser_la-normalize_oops.lo: normalize_oops.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbtparser_la_CFLAGS) $(CFLAGS) -MT libbtparser_la-normalize_oops.lo -MD -MP -MF $(DEPDIR)/libbtparser_la-normalize_oops.Tpo -c -o libbtparser_la-normalize_oops.lo `test -f 'normalize_oops.c' || echo '$(srcdir)/'`normalize_oops.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libbtparser_la-normalize_oops.Tpo $(DEPDIR)/libbtparser_la-normalize_oops.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='normalize_oops.c' object='libbtparser_la-normalize_oops.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbtparser_la_CFLAGS) $(CFLAGS) -c -o libbtparser_la-normalize_oops.lo `test -f 'normalize_oops.c' || echo '$(srcdir)/'`normalize_oops.c + libbtparser_la-sharedlib.lo: sharedlib.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbtparser_la_CFLAGS) $(CFLAGS) -MT libbtparser_la-sharedlib.lo -MD -MP -MF $(DEPDIR)/libbtparser_la-sharedlib.Tpo -c -o libbtparser_la-sharedlib.lo `test -f 'sharedlib.c' || echo '$(srcdir)/'`sharedlib.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libbtparser_la-sharedlib.Tpo $(DEPDIR)/libbtparser_la-sharedlib.Plo diff --git a/lib/normalize.h b/lib/normalize.h index 738a4f3..dcc024b 100644 --- a/lib/normalize.h +++ b/lib/normalize.h @@ -85,6 +85,13 @@ btp_normalize_paired_unknown_function_names(struct btp_thread *thread1, struct b void btp_normalize_optimize_thread(struct btp_thread *thread);
+/** + * Normalize thread created from kerneloops backtrace. NOT for use with + * userspace threads. + */ +void +btp_normalize_oops_thread(struct btp_thread *thread); + #ifdef __cplusplus } #endif diff --git a/lib/normalize_oops.c b/lib/normalize_oops.c new file mode 100644 index 0000000..5b2df56 --- /dev/null +++ b/lib/normalize_oops.c @@ -0,0 +1,72 @@ +/* + normalize_oops.c + + Copyright (C) 2010 Red Hat, 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. + + 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 "normalize.h" +#include "frame.h" +#include "thread.h" +#include "utils.h" +#include <stdlib.h> +#include <assert.h> + +static int ptrstrcmp(const void *s1, const void *s2) +{ + return btp_strcmp0(*(const char**)s1, *(const char**)s2); +} + +void +btp_normalize_oops_thread(struct btp_thread *thread) +{ + /* !!! MUST BE SORTED !!! */ + const char *blacklist[] = { + "do_softirq", + "do_vfs_ioctl", + "flush_kthread_worker", + "gs_change", + "irq_exit", + "kernel_thread_helper", + "kthread", + "process_one_work", + "system_call_fastpath", + "warn_slowpath_common", + "warn_slowpath_fmt", + "warn_slowpath_fmt_taint", + "warn_slowpath_null", + "worker_thread" + }; + + struct btp_frame *frame = thread->frames; + while (frame) + { + struct btp_frame *next_frame = frame->next; + + /* do not drop frames belonging to a module */ + bool in_module = (btp_strcmp0(frame->library_name, "vmlinux") != 0); + bool in_blacklist = bsearch(&(frame->function_name), blacklist, + sizeof(blacklist)/sizeof(blacklist[0]), + sizeof(blacklist[0]), ptrstrcmp); + + if (!in_module && in_blacklist) + { + bool success = btp_thread_remove_frame(thread, frame); + assert(success || !"failed to remove frame"); + } + + frame = next_frame; + } +} diff --git a/tests/normalize.at b/tests/normalize.at index d519757..a293c82 100644 --- a/tests/normalize.at +++ b/tests/normalize.at @@ -152,3 +152,52 @@ int main() return 0; } ]) + +AT_TESTFUN([btp_normalize_oops], +[ +UTILS + +#define t(name) (assert(f), assert(btp_strcmp0(f->function_name, name) == 0), f = f->next); + +int main() +{ + struct btp_thread *thread; + struct btp_frame *f; + + thread = create_thread(14, + "warn_slowpath_common", + "warn_slowpath_null", + "brcms_c_wait_for_tx_completion", + "brcms_ops_flush", + "ieee80211_scan_work", + "switch_to", + "process_one_work", + "ieee80211_run_deferred_scan", + "worker_thread", + "manage_workers", + "kthread", + "kernel_thread_helper", + "kthread_freezable_should_stop", + "gs_change" + ); + + for (f = thread->frames; f; f = f->next) + { + f->library_name = btp_strdup("vmlinux"); + } + + btp_normalize_oops_thread(thread); + + f = thread->frames; + t("brcms_c_wait_for_tx_completion"); + t("brcms_ops_flush"); + t("ieee80211_scan_work"); + t("switch_to"); + t("ieee80211_run_deferred_scan"); + t("manage_workers"); + t("kthread_freezable_should_stop"); + assert(f == NULL); + + return 0; +} +])