From: Stefan Behnel Date: Sat, 10 Jan 2009 15:50:43 +0000 (+0100) Subject: dump complete syntax tree path on compiler crashes, including nodes traversed in... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c3e964869694c9b19774155a67398dc55b2d785a;p=cython.git dump complete syntax tree path on compiler crashes, including nodes traversed in recursive calls that are not controlled by a transform --- diff --git a/Cython/Compiler/Visitor.py b/Cython/Compiler/Visitor.py index 72702026..0e67f36f 100644 --- a/Cython/Compiler/Visitor.py +++ b/Cython/Compiler/Visitor.py @@ -93,7 +93,8 @@ class TreeVisitor(BasicVisitor): self.access_path = [] def dump_node(self, node, indent=0): - ignored = list(node.child_attrs) + [u'child_attrs', u'pos'] + ignored = list(node.child_attrs) + [u'child_attrs', u'pos', + u'gil_message', u'subexprs'] values = [] pos = node.pos if pos: @@ -109,7 +110,10 @@ class TreeVisitor(BasicVisitor): continue if attr.startswith(u'_') or attr.endswith(u'_'): continue - value = getattr(node, attr, None) + try: + value = getattr(node, attr) + except AttributeError: + continue if value is None: continue elif isinstance(value, list): @@ -122,6 +126,23 @@ class TreeVisitor(BasicVisitor): return u'%s(%s)' % (node.__class__.__name__, u',\n '.join(values)) + def _find_node_path(self, stacktrace): + import os.path + last_traceback = stacktrace + nodes = [] + while hasattr(stacktrace, 'tb_frame'): + frame = stacktrace.tb_frame + node = frame.f_locals.get(u'self') + if isinstance(node, Nodes.Node): + code = frame.f_code + method_name = code.co_name + pos = (os.path.basename(code.co_filename), + code.co_firstlineno) + nodes.append((node, method_name, pos)) + last_traceback = stacktrace + stacktrace = stacktrace.tb_next + return (last_traceback, nodes) + def visitchild(self, child, parent, attrname, idx): self.access_path.append((parent, attrname, idx)) try: @@ -141,9 +162,15 @@ class TreeVisitor(BasicVisitor): trace.append(u'%s.%s%s = %s' % ( parent.__class__.__name__, attribute, index, self.dump_node(node))) + stacktrace, called_nodes = self._find_node_path(sys.exc_info()[2]) + last_node = child + for node, method_name, pos in called_nodes: + last_node = node + trace.append(u"File '%s', line %d, in %s: %s" % ( + pos[0], pos[1], method_name, self.dump_node(node))) raise Errors.CompilerCrash( - node.pos, self.__class__.__name__, - u'\n'.join(trace), e, sys.exc_info()[2]) + last_node.pos, self.__class__.__name__, + u'\n'.join(trace), e, stacktrace) self.access_path.pop() return result