diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-01-09 22:39:43 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-01-09 22:39:43 +0000 |
commit | 60e734782f24b671d6c70e6b3744a3c0aaf9475a (patch) | |
tree | d9224110eb3a23bae7f483955627faca89391cdf /clang/utils | |
parent | 6138f2b4d84964baacaaa8780f789d2bf835d978 (diff) | |
download | bcm5719-llvm-60e734782f24b671d6c70e6b3744a3c0aaf9475a.tar.gz bcm5719-llvm-60e734782f24b671d6c70e6b3744a3c0aaf9475a.zip |
Add utils/SummarizeErrors.
- Little script for scanning a compile log and summarizing warnings,
errors, assertions, and crashes.
- Is very slow, and stack trace regexs probably only work on Darwin.
llvm-svn: 62013
Diffstat (limited to 'clang/utils')
-rwxr-xr-x | clang/utils/SummarizeErrors | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/clang/utils/SummarizeErrors b/clang/utils/SummarizeErrors new file mode 100755 index 00000000000..ca3086d9b7f --- /dev/null +++ b/clang/utils/SummarizeErrors @@ -0,0 +1,99 @@ +#!/usr/bin/python + +import os, sys, re + +class multidict: + def __init__(self, elts=()): + self.data = {} + for key,value in elts: + self[key] = value + + def __getitem__(self, item): + return self.data[item] + def __setitem__(self, key, value): + if key in self.data: + self.data[key].append(value) + else: + self.data[key] = [value] + def items(self): + return self.data.items() + def values(self): + return self.data.values() + def keys(self): + return self.data.keys() + def __len__(self): + return len(self.data) + +kGCCErrorRE = re.compile('(.*):([0-9]+): error: (.*)') +kGCCWarningRE = re.compile('(.*):([0-9]+): warning: (.*)') +kClangErrorRE = re.compile('(.*):([0-9]+):([0-9]+): error: (.*)') +kClangWarningRE = re.compile('(.*):([0-9]+):([0-9]+): warning: (.*)') +kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)') +kStackDumpLineRE = re.compile('^[0-9]+ +([^ ]+) +0x[0-9a-fA-F]+ +([^ ]+)') + +def readInfo(path, opts): + f = open(path) + data = f.read() + f.close() + + if opts.truncate != -1: + data = data[:opts.truncate] + + gccwarnings = multidict([(m.group(3),m) for m in kGCCWarningRE.finditer(data)]).items() + gccerrors = multidict([(m.group(3),m) for m in kGCCErrorRE.finditer(data)]).items() + assertions = multidict([(m.group(1),m) for m in kAssertionRE.finditer(data)]).items() + + # Manual scan for stack traces + aborts = multidict() + prevLine = None + lnIter = iter(data.split('\n')) + for ln in lnIter: + m = kStackDumpLineRE.match(ln) + if m: + stack = [m.group(2)] + for ln in lnIter: + m = kStackDumpLineRE.match(ln) + if not m: + break + stack.append(m.group(2)) + if prevLine is None or not kAssertionRE.match(prevLine): + aborts[tuple(stack)] = stack + prevLine = ln + + sections = [ + (gccwarnings, 'Warnings'), + (gccerrors, 'Errors'), + (assertions, 'Assertions'), + (aborts.items(), 'Aborts'), + ] + + if opts.ascending: + sections.reverse() + + for l,title in sections: + l.sort(key = lambda (a,b): -len(b)) + if l: + print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l)) + for name,elts in l: + print '%5d:' % len(elts), name + +def main(): + global options + from optparse import OptionParser + parser = OptionParser("usage: %prog [options] {inputs}") + parser.add_option("", "--ascending", dest="ascending", + help="Print output in ascending order of severity.", + action="store_true", default=False) + parser.add_option("", "--truncate", dest="truncate", + help="Truncate input file (for testing).", + type=int, action="store", default=-1) + (opts, args) = parser.parse_args() + + if not args: + parser.error('No inputs specified') + + for arg in args: + readInfo(arg, opts) + +if __name__=='__main__': + main() |