# -*- coding: utf-8 -*- ## Copyright (C) 2001-2005 Red Hat, Inc. ## Copyright (C) 2001-2005 Harald Hoyer ## Copyright (C) 2009 Jiri Moskovcak ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """ Module for a userfriendly exception handling """ import sys import os import syslog import subprocess def write_dump(pid, tb): executable = "Exception raised from python shell" if sys.argv[0]: # FIXME: is this reliable?! # what if argv[0] is relative and we chdir'ed somewhere # during execution? executable = os.path.abspath(sys.argv[0]) command = ["/usr/libexec/abrt-hook-python"] command.append("--pid=%s" % pid) command.append("--executable=%s" % executable) helper = subprocess.Popen(command, stdin=subprocess.PIPE) helper.communicate(tb) helper.wait() def handleMyException((etype, value, tb)): """ The exception handling function. progname - the name of the application version - the version of the application """ # restore original exception handler sys.excepthook = sys.__excepthook__ # pylint: disable-msg=E1101 # ignore uncaught ctrl-c if etype == KeyboardInterrupt: return sys.__excepthook__(etype, value, tb) try: import os.path import traceback # "-c" appears in this case: # $ python -c 'import sys; print "argv0 is:%s" % sys.argv[0]' # argv0 is:-c if sys.argv[0] and sys.argv[0] != "-c": syslog.syslog("abrt: detected unhandled Python exception in %s" % sys.argv[0]) else: # interactive Python etc syslog.syslog("abrt: detected unhandled Python exception") elist = traceback.format_exception(etype, value, tb) tblast = traceback.extract_tb(tb, limit=None) if len(tblast): tblast = tblast[len(tblast)-1] extxt = traceback.format_exception_only(etype, value) if tblast and len(tblast) > 3: ll = [] ll.extend(tblast[:3]) ll[0] = os.path.basename(tblast[0]) tblast = ll ntext = "" for t in tblast: ntext += str(t) + ":" text = ntext text += extxt[0] text += "\n" text += "".join(elist) trace = tb while trace.tb_next: trace = trace.tb_next frame = trace.tb_frame text += ("\nLocal variables in innermost frame:\n") try: for (key, val) in frame.f_locals.items(): text += "%s: %s\n" % (key, repr(val)) except: pass # add coredump saving write_dump(os.getpid(), text) except: # silently ignore any error in this hook, # to not interfere with the python scripts pass return sys.__excepthook__(etype, value, tb) def installExceptionHandler(): """ Install the exception handling function. """ sys.excepthook = lambda etype, value, tb: handleMyException((etype, value, tb)) if __name__ == '__main__': # test exception raised to show the effect div0 = 1 / 0 # pylint: disable-msg=W0612 sys.exit(0) __author__ = "Harald Hoyer "