]> hydra-www.ietfng.org Git - dyna2/commitdiff
Try to improve python crash logging
authorNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Mon, 8 Jul 2013 03:30:05 +0000 (23:30 -0400)
committerNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Mon, 8 Jul 2013 03:30:05 +0000 (23:30 -0400)
This seems like it should work, but IPython seems to be getting in my way.

src/Dyna/Backend/Python/errors.py
src/Dyna/Backend/Python/interpreter.py

index 7d31fb46266e66a856d495763349e3f574f26bcd..f1be8a55a43c897b61be96c4e62112722da8d78e 100644 (file)
@@ -1,4 +1,4 @@
-import sys
+import readline, sys
 from IPython.core.ultratb import VerboseTB
 from utils import parse_attrs
 from config import dotdynadir
@@ -26,41 +26,51 @@ class DynaInitializerException(Exception):
         super(DynaInitializerException, self).__init__(msg)
 
 
-def exception_handler(etype, evalue, tb):
 
-    # once for the log file.
-    with file(dotdynadir / 'crash.log', 'wb') as crashreport:
-        h = VerboseTB(color_scheme='Linux',
-                      call_pdb=False,
-                      ostream=crashreport,
-                      long_header=True,
-                      include_vars=True,
-                      check_cache=None)
-        h(etype, evalue, tb)
+def crash_handler(interp):
+    """
+    Use our custom exception handler for handling uncaught exceptions.
+    """
 
-    show_traceback((etype, evalue, tb))
+    def exception_handler(etype, evalue, tb):
 
-    # TODO: we should package up all relevant state including compiler
-    # version, codegen output, interpreter state (possibly without the
-    # chart -- because it might be too big to email); input to repl.
-    # This should all go into a tarball.
+        print 'FATAL ERROR (%s): %s' % (etype.__name__, evalue)
 
-    if crash_handler.interp is not None:
-        crash_handler.interp()
+        # once for the log file.
+        with file(dotdynadir / 'crash.log', 'wb') as crashreport:
+            h = VerboseTB(color_scheme='Linux',
+                          call_pdb=False,
+                          ostream=crashreport,
+                          long_header=True,
+                          include_vars=True,
+                          check_cache=None)
+            h(etype, evalue, tb)
 
-    print 'FATAL ERROR (%s): %s' % (etype.__name__, evalue)
-    print 'Crash log available %s' % crashreport.name
 
+            # Dump the entirety of readline's history.  I do not think that
+            # we can easily distinguish what is this session or a different
+            # one, but this is more useful than nothing.
+            #
+            # XXX Well, that'd be great, except that it doesn't work.
 
-def crash_handler():
-    """
-    Use our custom exception handler for handling uncaught exceptions.
-    """
-    sys.excepthook = exception_handler
+            if interp is not None:
+                if interp._repl is not None:
+                    crashreport.write("REPL history:\n")
+                    for ix in xrange(1,readline.get_current_history_length()):
+                        crashreport.write("%d: %s\n" \
+                            % (ix,readline.get_history_entry(ix)))
+
+                # TODO: we should package up all relevant state including
+                # compiler version, codegen output, interpreter state
+                # (possibly without the chart -- because it might be too big
+                # to email); input to repl.  This should all go into a
+                # tarball.
 
-# XXX: global state...
-crash_handler.interp = None
+        show_traceback((etype, evalue, tb))
 
+        print 'Crash log available %s' % crashreport.name
+
+    sys.excepthook = exception_handler
 
 def show_traceback(einfo=None):
     if not einfo:
index b4b54d81b94fba178a3d53d949b390f7a2ad112f..7a7b9f934dcec8b6bf74cd475589b85d11f6cd92 100644 (file)
@@ -174,6 +174,8 @@ class Interpreter(object):
 
         self.files = []
 
+        self._repl = None
+
         # interpretor needs a place for it's temporary files.
         self.tmp = tmp = (dotdynadir / 'tmp' / str(os.getpid()))
         if tmp.exists():
@@ -507,7 +509,8 @@ class Interpreter(object):
 
     def repl(self):
         import repl
-        repl.REPL(self).cmdloop()
+        self._repl = repl.REPL(self)
+        self._repl.cmdloop()
 
     def do(self, filename, initialize=True):
         """
@@ -664,7 +667,7 @@ def main():
 
     interp = Interpreter()
 
-    crash_handler()
+    crash_handler(interp)
 
     if args.source: