[cfe-commits] r56606 - in /cfe/trunk: tools/scan-view/ScanView.py utils/scan-build
Daniel Dunbar
daniel at zuster.org
Wed Sep 24 23:05:32 PDT 2008
Author: ddunbar
Date: Thu Sep 25 01:05:31 2008
New Revision: 56606
URL: http://llvm.org/viewvc/llvm-project?rev=56606&view=rev
Log:
Add link to report analyzer failures (parse errors, asserts, etc).
Modified:
cfe/trunk/tools/scan-view/ScanView.py
cfe/trunk/utils/scan-build
Modified: cfe/trunk/tools/scan-view/ScanView.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/ScanView.py?rev=56606&r1=56605&r2=56606&view=diff
==============================================================================
--- cfe/trunk/tools/scan-view/ScanView.py (original)
+++ cfe/trunk/tools/scan-view/ScanView.py Thu Sep 25 01:05:31 2008
@@ -10,6 +10,7 @@
import threading
import time
import socket
+import itertools
import Reporter
import ConfigParser
@@ -21,6 +22,11 @@
kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->')
+# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" -->
+
+kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->')
+kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"')
+
kReportReplacements = []
# Add custom javascript.
@@ -54,6 +60,12 @@
kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'),
'<td class="Button"><a href="report/%(report)s">Report Bug</a></td>'))
+# Insert report crashes link.
+
+kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'),
+ '<br>These files will automatically be attached to ' +
+ 'reports filed here: <a href="report_crashes">Report Crashes</a>.'))
+
###
# Other simple parameters
@@ -176,7 +188,11 @@
name, value = chunk.split('=', 1)
name = urllib.unquote(name.replace('+', ' '))
value = urllib.unquote(value.replace('+', ' '))
- fields[name] = value
+ item = fields.get(name)
+ if item is None:
+ fields[name] = [value]
+ else:
+ item.append(value)
return fields
class ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
@@ -229,6 +245,17 @@
keys[k] = v
return keys
+ def load_crashes(self):
+ path = posixpath.join(self.server.root, 'index.html')
+ data = open(path).read()
+ problems = []
+ for item in kReportCrashEntryRE.finditer(data):
+ fieldData = item.group(1)
+ fields = dict([i.groups() for i in
+ kReportCrashEntryKeyValueRE.finditer(fieldData)])
+ problems.append(fields)
+ return problems
+
def handle_exception(self, exc):
import traceback
s = StringIO.StringIO()
@@ -238,18 +265,29 @@
if f:
self.copyfile(f, self.wfile)
f.close()
-
- def submit_bug(self):
- title = self.fields.get('title')
- description = self.fields.get('description')
- report = self.fields.get('report')
- reporterIndex = self.fields.get('reporter')
-
- # Type check form parameters.
- reportPath = posixpath.join(self.server.root,
- 'report-%s.html' % report)
- if not posixpath.exists(reportPath):
- return (False, "Invalid report ID.")
+
+ def get_scalar_field(self, name):
+ if name in self.fields:
+ return self.fields[name][0]
+ else:
+ return None
+
+ def submit_bug(self, c):
+ title = self.get_scalar_field('title')
+ description = self.get_scalar_field('description')
+ report = self.get_scalar_field('report')
+ reporterIndex = self.get_scalar_field('reporter')
+ files = []
+ for fileID in self.fields.get('files',[]):
+ try:
+ i = int(fileID)
+ except:
+ i = None
+ if i is None or i<0 or i>=len(c.files):
+ return (False, 'Invalid file ID')
+ files.append(c.files[i])
+ print files
+
if not title:
return (False, "Missing title.")
if not description:
@@ -268,15 +306,16 @@
return (False,
'Missing field "%s" for %s report method.'%(name,
reporter.getName()))
- parameters[o] = self.fields[name]
+ parameters[o] = self.get_scalar_field(name)
# Update config defaults.
- self.server.config.set('ScanView', 'reporter', reporterIndex)
- for o in reporter.getParameterNames():
- self.server.config.set(reporter.getName(), o, parameters[o])
+ if report != 'None':
+ self.server.config.set('ScanView', 'reporter', reporterIndex)
+ for o in reporter.getParameterNames():
+ self.server.config.set(reporter.getName(), o, parameters[o])
# Create the report.
- bug = Reporter.BugReport(title, description, [reportPath])
+ bug = Reporter.BugReport(title, description, files)
# Kick off a reporting thread.
t = ReporterThread(bug, reporter, parameters, self.server)
@@ -290,11 +329,21 @@
return (t.success, t.status)
def send_report_submit(self):
- report = self.fields.get('report')
- title = self.fields.get('title')
- description = self.fields.get('description')
+ print self.fields
+ report = self.get_scalar_field('report')
+ c = self.get_report_context(report)
+ if c.reportSource is None:
+ reportingFor = "Report Crashes > "
+ fileBug = """\
+<a href="/report_crashes">File Bug</a> > """%locals()
+ else:
+ reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource,
+ report)
+ fileBug = '<a href="/report/%s">File Bug</a> > ' % report
+ title = self.get_scalar_field('title')
+ description = self.get_scalar_field('description')
- res,message = self.submit_bug()
+ res,message = self.submit_bug(c)
if res:
statusClass = 'SubmitOk'
@@ -311,8 +360,8 @@
<body>
<h3>
<a href="/">Summary</a> >
-<a href="/report-%(report)s.html">Report %(report)s</a> >
-<a href="/report/%(report)s">File Bug</a> >
+%(reportingFor)s
+%(fileBug)s
Submit</h3>
<form name="form" action="">
<table class="form">
@@ -367,28 +416,106 @@
return self.send_string(res, 'text/plain')
- def send_report(self, report):
- try:
- keys = self.load_report(report)
- except IOError:
- return self.send_error(400, 'Invalid report.')
+ def get_report_context(self, report):
+ class Context:
+ pass
+ if report is None or report == 'None':
+ data = self.load_crashes()
+ # Don't allow empty reports.
+ if not data:
+ raise ValueError, 'No crashes detected!'
+ c = Context()
+ c.title = 'clang static analyzer failures'
+
+ stderrSummary = ""
+ for item in data:
+ if 'stderr' in item:
+ path = posixpath.join(self.server.root, item['stderr'])
+ if os.path.exists(path):
+ lns = itertools.islice(open(path), 0, 10)
+ stderrSummary += '%s\n--\n%s' % (item.get('src',
+ '<unknown>'),
+ ''.join(lns))
+
+ c.description = """\
+The clang static analyzer failed on these inputs:
+%s
- initialTitle = keys.get('DESC','')
- initialDescription = """\
-Bug generated by the clang static analyzer.
+STDERR Summary
+--------------
+%s
+""" % ('\n'.join([item.get('src','<unknown>') for item in data]),
+ stderrSummary)
+ c.reportSource = None
+ c.navMarkup = "Report Crashes > "
+ c.files = []
+ for item in data:
+ c.files.append(item.get('src',''))
+ c.files.append(posixpath.join(self.server.root,
+ item.get('file','')))
+ c.files.append(posixpath.join(self.server.root,
+ item.get('clangfile','')))
+ c.files.append(posixpath.join(self.server.root,
+ item.get('stderr','')))
+ c.files.append(posixpath.join(self.server.root,
+ item.get('info','')))
+ # Just in case something failed, ignore files which don't
+ # exist.
+ c.files = [f for f in c.files
+ if os.path.exists(f) and os.path.isfile(f)]
+ else:
+ # Check that this is a valid report.
+ path = posixpath.join(self.server.root, 'report-%s.html' % report)
+ if not posixpath.exists(path):
+ raise ValueError, 'Invalid report ID'
+ keys = self.load_report(report)
+ c = Context()
+ c.title = keys.get('DESC','clang error (unrecognized')
+ c.description = """\
+Bug reported by the clang static analyzer.
Description: %s
File: %s
Line: %s
-"""%(initialTitle,
- keys.get('FILE','<unknown>'),
- keys.get('LINE','<unknown>'))
+"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>'))
+ c.reportSource = 'report-%s.html' % report
+ c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource,
+ report)
+
+ c.files = [path]
+ return c
+
+ def send_report(self, report, configOverrides=None):
+ def getConfigOption(section, field):
+ if (configOverrides is not None and
+ section in configOverrides and
+ field in configOverrides[section]):
+ return configOverrides[section][field]
+ return self.server.config.get(section, field)
+
+ # report is None is used for crashes
+ try:
+ c = self.get_report_context(report)
+ except ValueError, e:
+ return self.send_error(400, e.message)
+
+ title = c.title
+ description= c.description
+ reportingFor = c.navMarkup
+ if c.reportSource is None:
+ extraIFrame = ""
+ else:
+ extraIFrame = """\
+<iframe src="/%s" width="100%%" height="40%%"
+ scrolling="auto" frameborder="1">
+ <a href="/%s">View Bug Report</a>
+</iframe>""" % (c.reportSource, c.reportSource)
reporterSelections = []
reporterOptions = []
-
+
try:
- active = self.server.config.getint('ScanView','reporter')
+ active = int(getConfigOption('ScanView','reporter'))
except:
active = 0
for i,r in enumerate(self.server.reporters):
@@ -402,7 +529,7 @@
<tr>
<td class="form_clabel">%s:</td>
<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
-</tr>"""%(o,r.getName(),o,self.server.config.get(r.getName(), o)) for o in r.getParameterNames()])
+</tr>"""%(o,r.getName(),o,getConfigOption(r.getName(),o)) for o in r.getParameterNames()])
display = ('none','')[selected]
reporterOptions.append("""\
<tr id="%sReporterOptions" style="display:%s">
@@ -418,6 +545,23 @@
reporterOptionsDivs = '\n'.join(reporterOptions)
reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters]))
+ if c.files:
+ fieldSize = min(5, len(c.files))
+ attachFileOptions = '\n'.join(["""\
+<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)])
+ attachFileRow = """\
+<tr>
+ <td class="form_label">Attach:</td>
+ <td class="form_value">
+<select style="width:100%%" name="files" multiple size=%d>
+%s
+</select>
+ </td>
+</tr>
+""" % (min(5, len(c.files)), attachFileOptions)
+ else:
+ attachFileRow = ""
+
result = """<html>
<head>
<title>File Bug</title>
@@ -440,7 +584,7 @@
<body onLoad="updateReporterOptions()">
<h3>
<a href="/">Summary</a> >
-<a href="/report-%(report)s.html">Report %(report)s</a> >
+%(reportingFor)s
File Bug</h3>
<form name="form" action="/report_submit" method="post">
<input type="hidden" name="report" value="%(report)s">
@@ -451,16 +595,20 @@
<tr>
<td class="form_clabel">Title:</td>
<td class="form_value">
- <input type="text" name="title" size="50" value="%(initialTitle)s">
+ <input type="text" name="title" size="50" value="%(title)s">
</td>
</tr>
<tr>
<td class="form_label">Description:</td>
<td class="form_value">
<textarea rows="10" cols="80" name="description">
-%(initialDescription)s
+%(description)s
</textarea>
</td>
+</tr>
+
+%(attachFileRow)s
+
</table>
<br>
<table class="form_group">
@@ -482,13 +630,11 @@
</table>
</form>
-<iframe src="/report-%(report)s.html" width="100%%" height="40%%"
- scrolling="auto" frameborder="1">
- <a href="/report-%(report)s.html">View Bug Report</a>
-</iframe>
+%(extraIFrame)s
</body>
</html>"""%locals()
+
return self.send_string(result)
def send_head(self, fields=None):
@@ -521,6 +667,17 @@
return self.send_string('Goodbye.', 'text/plain')
elif name=='report_submit':
return self.send_report_submit()
+ elif name=='report_crashes':
+ overrides = { 'ScanView' : {},
+ 'Radar' : {},
+ 'Email' : {} }
+ for i,r in enumerate(self.server.reporters):
+ if r.getName() == 'Radar':
+ overrides['ScanView']['reporter'] = i
+ break
+ overrides['Radar']['Component'] = 'llvm - checker'
+ overrides['Radar']['Component Version'] = 'X'
+ return self.send_report(None, overrides)
elif name=='favicon.ico':
return self.send_path(posixpath.join(kResources,'bugcatcher.ico'))
Modified: cfe/trunk/utils/scan-build
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/scan-build?rev=56606&r1=56605&r2=56606&view=diff
==============================================================================
--- cfe/trunk/utils/scan-build (original)
+++ cfe/trunk/utils/scan-build Thu Sep 25 01:05:31 2008
@@ -687,7 +687,7 @@
print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"crashes/$ppfile\">$ppfile</a></td><td><a href=\"crashes/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
my $ppfile_clang = $ppfile;
$ppfile_clang =~ s/[.](.+)$/.clang.$1/;
- print OUT " <!-- REPORTPROBLEM file=\"crashes/$ppfile\" clangfile=\"crashes/$ppfile_clang\" stderr=\"crashes/$ppfile.stderr.txt\" info=\"crashes/$ppfile.info\" -->\n";
+ print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"crashes/$ppfile\" clangfile=\"crashes/$ppfile_clang\" stderr=\"crashes/$ppfile.stderr.txt\" info=\"crashes/$ppfile.info.txt\" -->\n";
}
print OUT <<ENDTEXT;
More information about the cfe-commits
mailing list