зеркало из https://github.com/microsoft/clang.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62013 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c9b580a4de
Коммит
ef64fcfbfb
|
@ -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()
|
Загрузка…
Ссылка в новой задаче