diff options
-rw-r--r-- | src/Backtrace/backtrace.c | 90 | ||||
-rw-r--r-- | src/Backtrace/backtrace.h | 6 | ||||
-rw-r--r-- | src/Backtrace/main.c | 21 | ||||
-rw-r--r-- | src/Daemon/Daemon.cpp | 4 |
4 files changed, 112 insertions, 9 deletions
diff --git a/src/Backtrace/backtrace.c b/src/Backtrace/backtrace.c index 5a112732..c9761d12 100644 --- a/src/Backtrace/backtrace.c +++ b/src/Backtrace/backtrace.c @@ -85,6 +85,56 @@ static bool frame_is_exit_handler(struct frame *frame) && NULL != strstr(frame->sourcefile, "exit.c")); } +static bool frame_is_noncrash_frame(struct frame *frame) +{ + if (!frame->function) + return false; + + if (0 == strcmp(frame->function, "__kernel_vsyscall")) + return true; + + if (!frame->sourcefile) + return false; + + if (0 == strcmp(frame->function, "_XReply") + && 0 == strcmp(frame->sourcefile, "xcb_io.c")) + return true; + + if (0 == strcmp(frame->function, "_XError") + && 0 == strcmp(frame->sourcefile, "XlibInt.c")) + return true; + + if (0 == strcmp(frame->function, "gdk_x_error") + && 0 == strcmp(frame->sourcefile, "gdkmain-x11.c")) + return true; + + if (0 == strcmp(frame->function, "IA__g_log") + && 0 == strcmp(frame->sourcefile, "gmessages.c")) + return true; + + if (0 == strcmp(frame->function, "IA__g_logv") + && 0 == strcmp(frame->sourcefile, "gmessages.c")) + return true; + + if (0 == strcmp(frame->function, "process_responses") + && 0 == strcmp(frame->sourcefile, "xcb_io.c")) + return true; + + if (0 == strcmp(frame->function, "XSync") + && 0 == strcmp(frame->sourcefile, "Sync.c")) + return true; + + /* DBus */ + if (0 == strcmp(frame->function, "gerror_to_dbus_error_message") + && 0 == strcmp(frame->sourcefile, "dbus-gobject.c")) + return true; + if (0 == strcmp(frame->function, "dbus_g_method_return_error") + && 0 == strcmp(frame->sourcefile, "dbus-gobject.c")) + return true; + + return false; +} + struct thread *thread_new() { struct thread *t = malloc(sizeof(struct thread)); @@ -204,6 +254,36 @@ static void thread_remove_exit_handlers(struct thread *thread) } } +void thread_remove_noncrash_frames(struct thread *thread) +{ + struct frame *prev = NULL; + struct frame *cur = thread->frames; + while (cur) + { + if (frame_is_noncrash_frame(cur)) + { + /* This frame must be skipped, because it will + be deleted. */ + if (prev) + prev->next = cur->next; + else + thread->frames = cur->next; + + frame_free(cur); + + /* Set cur to be valid, as it will be used to + advance to next item. */ + if (prev) + cur = prev; + else + cur = thread->frames; + } + + prev = cur; + cur = cur->next; + } +} + struct backtrace *backtrace_new() { struct backtrace *bt = malloc(sizeof(struct backtrace)); @@ -398,3 +478,13 @@ void backtrace_remove_exit_handlers(struct backtrace *backtrace) } } +void backtrace_remove_noncrash_frames(struct backtrace *backtrace) +{ + struct thread *thread = backtrace->threads; + while (thread) + { + thread_remove_noncrash_frames(thread); + thread = thread->next; + } +} + diff --git a/src/Backtrace/backtrace.h b/src/Backtrace/backtrace.h index ed6d3151..93897e93 100644 --- a/src/Backtrace/backtrace.h +++ b/src/Backtrace/backtrace.h @@ -88,6 +88,12 @@ extern void backtrace_limit_frame_depth(struct backtrace *backtrace, int depth); */ extern void backtrace_remove_exit_handlers(struct backtrace *backtrace); +/* + * Removes frames known as not causing crash, but that are often + * a part of a backtrace. + */ +extern void backtrace_remove_noncrash_frames(struct backtrace *backtrace); + /* Defined in parser.y. */ extern struct backtrace *do_parse(char *input, bool debug_parser, bool debug_scanner); diff --git a/src/Backtrace/main.c b/src/Backtrace/main.c index 8add8c42..7dfba431 100644 --- a/src/Backtrace/main.c +++ b/src/Backtrace/main.c @@ -40,13 +40,14 @@ static char doc[] = "abrt-backtrace -- backtrace analyzer"; static char args_doc[] = "FILE"; static struct argp_option options[] = { - {"independent" , 'i', 0 , 0, "Prints independent backtrace (fallback)" }, - {"single-thread" , 'n', 0 , 0, "Display the crash thread only in the backtrace" }, - {"frame-depth" , 'd', "N", 0, "Display only top N frames under the crash frame" }, - {"remove-exit-handlers" , 'r', 0 , 0, "Removes exit handlers from the displayed backtrace" }, - {"debug-parser" , 'p', 0 , 0, "Prints parser debug information"}, - {"debug-scanner" , 's', 0 , 0, "Prints scanner debug information"}, - {"verbose" , 'v', 0 , 0, "Print human-friendly superfluous output."}, + {"independent" , 'i', 0 , 0, "Prints independent backtrace (fallback)"}, + {"single-thread" , 'n', 0 , 0, "Display the crash thread only in the backtrace"}, + {"frame-depth" , 'd', "N", 0, "Display only top N frames under the crash frame"}, + {"remove-exit-handlers" , 'r', 0 , 0, "Removes exit handler frames from the displayed backtrace"}, + {"remove-noncrash-frames", 'm', 0 , 0, "Removes common frames known as not causing crash"}, + {"debug-parser" , 'p', 0 , 0, "Prints parser debug information"}, + {"debug-scanner" , 's', 0 , 0, "Prints scanner debug information"}, + {"verbose" , 'v', 0 , 0, "Print human-friendly superfluous output."}, { 0 } }; @@ -56,6 +57,7 @@ struct arguments bool single_thread; int frame_depth; /* negative == do not limit the depth */ bool remove_exit_handlers; + bool remove_noncrash_frames; bool debug_parser; bool debug_scanner; bool verbose; @@ -82,6 +84,7 @@ parse_opt (int key, char *arg, struct argp_state *state) } break; case 'r': arguments->remove_exit_handlers = true; break; + case 'm': arguments->remove_noncrash_frames = true; break; case 'p': arguments->debug_parser = true; break; case 's': arguments->debug_scanner = true; break; case 'v': arguments->verbose = true; break; @@ -119,6 +122,7 @@ int main(int argc, char **argv) arguments.frame_depth = -1; arguments.single_thread = false; arguments.remove_exit_handlers = false; + arguments.remove_noncrash_frames = false; arguments.debug_parser = false; arguments.debug_scanner = false; arguments.verbose = false; @@ -310,6 +314,9 @@ int main(int argc, char **argv) } } + if (arguments.remove_noncrash_frames) + backtrace_remove_noncrash_frames(backtrace); + /* If a frame removal is requested, do it now. */ if (arguments.frame_depth > 0) backtrace_limit_frame_depth(backtrace, arguments.frame_depth); diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index 1e934bc0..8038f75d 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -1,4 +1,4 @@ -/* +/* -*-mode:c++;c-file-style:"bsd";c-basic-offset:4;indent-tabs-mode:nil-*- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) Copyright (C) 2009 RedHat inc. @@ -651,7 +651,7 @@ static void ensure_writable_dir(const char *dir, mode_t mode, const char *group) perror_msg_and_die("Can't find group '%s'", group); if ((sb.st_uid != 0 || sb.st_gid != gr->gr_gid) && chown(dir, 0, gr->gr_gid) != 0) - perror_msg_and_die("Can't set owner 0:0 on '%s'", dir); + perror_msg_and_die("Can't set owner 0:%u on '%s'", (unsigned int)gr->gr_gid, dir); if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0) perror_msg_and_die("Can't set mode %o on '%s'", mode, dir); } |