summaryrefslogtreecommitdiffstats
path: root/src/Backtrace
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-02-04 19:23:22 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-02-04 19:23:22 +0100
commitf9d98f594a2b5103f0e88bf33191ad164a77c239 (patch)
tree59edafbb544aef35be63dadf09e6e448e27afc6d /src/Backtrace
parentb634e1a482f6871bb4e128f3bc23456f09f85547 (diff)
parentbaacc3cadfd08293e6f46bd84ab322d0cb67bf10 (diff)
Merge branch 'master' into rhel6
Diffstat (limited to 'src/Backtrace')
-rwxr-xr-xsrc/Backtrace/abrt-bz-dupchecker42
-rwxr-xr-xsrc/Backtrace/abrt-bz-hashchecker59
-rw-r--r--src/Backtrace/backtrace.c41
-rw-r--r--src/Backtrace/parser.y6
4 files changed, 118 insertions, 30 deletions
diff --git a/src/Backtrace/abrt-bz-dupchecker b/src/Backtrace/abrt-bz-dupchecker
index 4484d39..d7748c7 100755
--- a/src/Backtrace/abrt-bz-dupchecker
+++ b/src/Backtrace/abrt-bz-dupchecker
@@ -62,6 +62,8 @@ for buginfo in buginfos:
print "Bug {0} has status {1}, skipping.".format(buginfo.bug_id, buginfo.bug_status)
continue
+ bug = bz.getbug(buginfo.bug_id)
+
# Skip bugs with already downloaded backtraces.
filename = "{0}.bt".format(buginfo.bug_id)
if os.path.isfile(filename):
@@ -69,7 +71,6 @@ for buginfo in buginfos:
print "Skipping {0} (already exists).".format(filename)
else:
# Get backtrace from bug and store it as a file.
- bug = bz.getbug(buginfo.bug_id)
downloaded = False
for attachment in bug.attachments:
if attachment['filename'] == 'backtrace':
@@ -95,7 +96,7 @@ for buginfo in buginfos:
command.append("--remove-noncrash-frames")
helper = subprocess.Popen(command, stdout=subprocess.PIPE)
- out, err = helper.communicate()
+ backtrace, err = helper.communicate()
helper.wait()
if helper.returncode != 0:
@@ -103,16 +104,21 @@ for buginfo in buginfos:
continue
# Empty backtrace is provided by Python apps.
- if len(out) == 0:
+ if len(backtrace) == 0:
continue
- if out in database:
- database[out].append(buginfo.bug_id)
- if options.verbose:
- print "Duplicate found: {0}".format(database[out])
- print "Backtrace: {0}".format(out)
+ bugitem = {'id':buginfo.bug_id, 'comments':len(bug.longdescs)}
+ if backtrace in database:
+ components = database[backtrace]
+ if buginfo.component in components:
+ components[buginfo.component].append(bugitem)
+ if options.verbose:
+ print "Duplicate found: {0}".format(database[out]['id'])
+ print "Backtrace: {0}".format(out)
+ else:
+ components[buginfo.component] = [ bugitem ]
else:
- database[out] = [ buginfo.bug_id ]
+ database[backtrace] = { buginfo.component: [ bugitem ] }
bz.logout()
@@ -121,14 +127,18 @@ print "=========================================================================
# The number of duplicates.
dupcount = 0
-for key, value in database.items():
- if len(value) > 1:
- dupcount += len(value) - 1
+for backtrace, components in database.items():
+ for component, bugitems in components.items():
+ if len(bugitems) > 1:
+ dupcount += len(value) - 1
print "Total number of duplicate bugs detected: {0}".format(dupcount)
print "------------------------------"
-for key, value in database.items():
- if len(value) > 1:
- print "Duplicates: {0}".format(value)
- print "Backtrace: {0}".format(key)
+# Print the duplicates
+for backtrace, components in database.items():
+ for component, bugitems in components.items():
+ if len(bugitems) > 1:
+ print "Component: {0}".format(component)
+ print "Duplicates: {0}".format(map(lambda x: "{0} ({1})".format(x['id'],x['comments']), bugitems).join(", "))
+ print "Backtrace: {0}".format(backtrace)
diff --git a/src/Backtrace/abrt-bz-hashchecker b/src/Backtrace/abrt-bz-hashchecker
new file mode 100755
index 0000000..9c4a5ff
--- /dev/null
+++ b/src/Backtrace/abrt-bz-hashchecker
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+# -*- mode:python -*-
+# Checks how many bugs in Bugzilla have the same hash.
+#
+# Please do not run this script unless it's neccessary to do so.
+# It forces Bugzilla to send data related to thousands of bug reports.
+
+from bugzilla import RHBugzilla
+from optparse import OptionParser
+import sys
+import os.path
+import subprocess
+import re
+
+parser = OptionParser(version="%prog 1.0")
+parser.add_option("-u", "--user", dest="user",
+ help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
+parser.add_option("-p", "--password", dest="password",
+ help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
+parser.add_option("-b", "--bugzilla", dest="bugzilla",
+ help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
+
+(options, args) = parser.parse_args()
+
+if not options.user or len(options.user) == 0:
+ parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
+
+if not options.password or len(options.password) == 0:
+ parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
+
+if not options.bugzilla or len(options.bugzilla) == 0:
+ options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
+
+bz = RHBugzilla()
+bz.connect(options.bugzilla)
+bz.login(options.user, options.password)
+
+buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
+
+print "{0} bugs found.".format(len(buginfos))
+
+hashes = {}
+for buginfo in buginfos:
+ match = re.search("abrt_hash:([^ ]+)", buginfo.status_whiteboard)
+ if not match:
+ continue
+ hash = match.group(1)
+ if not hash:
+ continue
+ if hash in hashes:
+ hashes[hash].append(buginfo.bug_id)
+ else:
+ hashes[hash] = [ buginfo.bug_id ]
+ print hash
+bz.logout()
+
+for hash, ids in hashes.items():
+ if len(ids) > 1:
+ print "Duplicates found: ", ids.join(", ")
diff --git a/src/Backtrace/backtrace.c b/src/Backtrace/backtrace.c
index b65216b..9b697da 100644
--- a/src/Backtrace/backtrace.c
+++ b/src/Backtrace/backtrace.c
@@ -129,32 +129,37 @@ static bool frame_is_noncrash_frame(struct frame *frame)
if (!frame->sourcefile)
return false;
+ /* GDK */
+ if (0 == strcmp(frame->function, "gdk_x_error")
+ && 0 == strcmp(frame->sourcefile, "gdkmain-x11.c"))
+ return true;
+
+ /* X.org */
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"))
+ if (0 == strcmp(frame->function, "XSync")
+ && 0 == strcmp(frame->sourcefile, "Sync.c"))
+ return true;
+ if (0 == strcmp(frame->function, "process_responses")
+ && 0 == strcmp(frame->sourcefile, "xcb_io.c"))
return true;
+ /* glib */
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"))
+ if (0 == strcmp(frame->function, "IA__g_assertion_message")
+ && 0 == strcmp(frame->sourcefile, "gtestutils.c"))
return true;
-
- if (0 == strcmp(frame->function, "XSync")
- && 0 == strcmp(frame->sourcefile, "Sync.c"))
+ if (0 == strcmp(frame->function, "IA__g_assertion_message_expr")
+ && 0 == strcmp(frame->sourcefile, "gtestutils.c"))
return true;
/* DBus */
@@ -165,6 +170,20 @@ static bool frame_is_noncrash_frame(struct frame *frame)
&& 0 == strcmp(frame->sourcefile, "dbus-gobject.c"))
return true;
+ /* libstdc++ */
+ if (0 == strcmp(frame->function, "__gnu_cxx::__verbose_terminate_handler")
+ && NULL != strstr(frame->sourcefile, "/vterminate.cc"))
+ return true;
+ if (0 == strcmp(frame->function, "__cxxabiv1::__terminate")
+ && NULL != strstr(frame->sourcefile, "/eh_terminate.cc"))
+ return true;
+ if (0 == strcmp(frame->function, "std::terminate")
+ && NULL != strstr(frame->sourcefile, "/eh_terminate.cc"))
+ return true;
+ if (0 == strcmp(frame->function, "__cxxabiv1::__cxa_throw")
+ && NULL != strstr(frame->sourcefile, "/eh_throw.cc"))
+ return true;
+
return false;
}
diff --git a/src/Backtrace/parser.y b/src/Backtrace/parser.y
index 1903282..42ac220 100644
--- a/src/Backtrace/parser.y
+++ b/src/Backtrace/parser.y
@@ -129,7 +129,7 @@ backtrace : /* empty */ %dprec 1
;
threads : thread
- | threads wsa thread { $$ = thread_add_sibling($1, $3); }
+ | threads '\n' thread { $$ = thread_add_sibling($1, $3); }
;
thread : keyword_thread wss digit_sequence wsa '(' keyword_thread wss digit_sequence wsa ')' ':' wsa frames
@@ -147,8 +147,8 @@ thread : keyword_thread wss digit_sequence wsa '(' keyword_thread wss digit_s
}
;
-frames : frame { $$ = $1; }
- | frames wsa frame { $$ = frame_add_sibling($1, $3); }
+frames : frame { $$ = $1; }
+ | frames frame { $$ = frame_add_sibling($1, $2); }
;
frame : frame_head_1 wss variables %dprec 3