diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-10-17 23:10:09 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-10-17 23:10:09 +0000 |
commit | d0e3ed0b01ba7e55081e5b2593460b7b1486fd24 (patch) | |
tree | 38ef8ff2978259425fb6fc6a9cf218778cd7c4a0 /utils/analyzer/exploded-graph-rewriter.py | |
parent | 40a1cfa0b13160d82f688daa7fbab9f249679617 (diff) | |
download | clang-d0e3ed0b01ba7e55081e5b2593460b7b1486fd24.tar.gz |
[analyzer] Assign truly stable identifiers to exploded nodes.
ExplodedGraph nodes will now have a numeric identifier stored in them
which will keep track of the order in which the nodes were created
and it will be fully deterministic both accross runs and across machines.
This is extremely useful for debugging as it allows reliably setting
conditional breakpoints by node IDs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/analyzer/exploded-graph-rewriter.py')
-rwxr-xr-x | utils/analyzer/exploded-graph-rewriter.py | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/utils/analyzer/exploded-graph-rewriter.py b/utils/analyzer/exploded-graph-rewriter.py index 77da7392e3..79222bdbe9 100755 --- a/utils/analyzer/exploded-graph-rewriter.py +++ b/utils/analyzer/exploded-graph-rewriter.py @@ -67,6 +67,9 @@ class ProgramPoint(object): super(ProgramPoint, self).__init__() self.kind = json_pp['kind'] self.tag = json_pp['tag'] + self.node_id = json_pp['node_id'] + self.is_sink = bool(json_pp['is_sink']) + self.has_report = bool(json_pp['has_report']) if self.kind == 'Edge': self.src_id = json_pp['src_id'] self.dst_id = json_pp['dst_id'] @@ -309,11 +312,9 @@ class ExplodedNode(object): def construct(self, node_id, json_node): logging.debug('Adding ' + node_id) - self.node_id = json_node['node_id'] - self.ptr = json_node['pointer'] - self.has_report = json_node['has_report'] - self.is_sink = json_node['is_sink'] + self.ptr = node_id[4:] self.points = [ProgramPoint(p) for p in json_node['program_points']] + self.node_id = self.points[-1].node_id self.state = ProgramState(json_node['state_id'], json_node['program_state']) \ if json_node['program_state'] is not None else None @@ -488,12 +489,14 @@ class DotDumpVisitor(object): else: color = 'forestgreen' + self._dump('<tr><td align="left">%s.</td>' % p.node_id) + if p.kind == 'Statement': # This avoids pretty-printing huge statements such as CompoundStmt. # Such statements show up only at [Pre|Post]StmtPurgeDeadSymbols skip_pretty = 'PurgeDeadSymbols' in p.stmt_point_kind stmt_color = 'cyan3' - self._dump('<tr><td align="left" width="0">%s:</td>' + self._dump('<td align="left" width="0">%s:</td>' '<td align="left" width="0"><font color="%s">' '%s</font> </td>' '<td align="left"><i>S%s</i></td>' @@ -506,30 +509,41 @@ class DotDumpVisitor(object): self._short_pretty(p.pretty) if not skip_pretty else '')) elif p.kind == 'Edge': - self._dump('<tr><td width="0"></td>' + self._dump('<td width="0"></td>' '<td align="left" width="0">' '<font color="%s">%s</font></td><td align="left">' '[B%d] -\\> [B%d]</td></tr>' % (color, 'BlockEdge', p.src_id, p.dst_id)) elif p.kind == 'BlockEntrance': - self._dump('<tr><td width="0"></td>' + self._dump('<td width="0"></td>' '<td align="left" width="0">' '<font color="%s">%s</font></td>' '<td align="left">[B%d]</td></tr>' % (color, p.kind, p.block_id)) else: # TODO: Print more stuff for other kinds of points. - self._dump('<tr><td width="0"></td>' + self._dump('<td width="0"></td>' '<td align="left" width="0" colspan="2">' '<font color="%s">%s</font></td></tr>' % (color, p.kind)) if p.tag is not None: - self._dump('<tr><td width="0"></td>' + self._dump('<tr><td width="0"></td><td width="0"></td>' '<td colspan="3" align="left">' '<b>Tag: </b> <font color="crimson">' '%s</font></td></tr>' % p.tag) + if p.has_report: + self._dump('<tr><td width="0"></td><td width="0"></td>' + '<td colspan="3" align="left">' + '<font color="red"><b>Bug Report Attached' + '</b></font></td></tr>') + if p.is_sink: + self._dump('<tr><td width="0"></td><td width="0"></td>' + '<td colspan="3" align="left">' + '<font color="cornflowerblue"><b>Sink Node' + '</b></font></td></tr>') + def visit_environment(self, e, prev_e=None): self._dump('<table border="0">') @@ -786,17 +800,10 @@ class DotDumpVisitor(object): self._dump('color="white",fontcolor="gray80",') self._dump('label=<<table border="0">') - self._dump('<tr><td bgcolor="%s"><b>Node %d (%s) - ' - 'State %s</b></td></tr>' + self._dump('<tr><td bgcolor="%s"><b>State %s</b></td></tr>' % ("gray20" if self._dark_mode else "gray70", - node.node_id, node.ptr, node.state.state_id + node.state.state_id if node.state is not None else 'Unspecified')) - if node.has_report: - self._dump('<tr><td><font color="red"><b>Bug Report Attached' - '</b></font></td></tr>') - if node.is_sink: - self._dump('<tr><td><font color="cornflowerblue"><b>Sink Node' - '</b></font></td></tr>') if not self._topo_mode: self._dump('<tr><td align="left" width="0">') if len(node.points) > 1: |