代码之家  ›  专栏  ›  技术社区  ›  Cloud

线程崩溃时自动生成到STDERR的完整堆栈跟踪

  •  0
  • Cloud  · 技术社区  · 8 年前

    问题

    A problem occurred in a Python script.  Here is the sequence of
    function calls leading up to the error, in the order they occurred.
    

    我还尝试了GDB(它对我的C/C++项目起到了神奇的作用) using a guide I found on StackOverflow to get "Python plus GDB" working


    问题

    在Python2.7中,当发生此类问题(即库调用使调用线程崩溃)时,是否可以强制线程(当它崩溃时)向STDOUT、STDERR或日志文件报告完整的堆栈跟踪?

    谢谢您。

    1 回复  |  直到 6 年前
        1
  •  1
  •   gbtimmon    8 年前

    如果您有权访问线程定义——您可以编写一个包装线程

    import logger 
    log = logger.getLogger(__name__)
    
    class WrapperThread(threading.Thread):
        def __init__(self, innerThread):
    
            self.innerThread = innerThread
    
        def start(self):
            try:
                # run the thread in the current context with run. 
                self.innerThread.run()
            except Exception as e:
                log.error("%s has crashed.", self, exc_info=True) #Exec info makes loggin print the stack trace. 
    

    根据所使用的库,您可能能够对线程定义应用修饰符。尽管我不建议在发布的代码中包含这样的代码

    import threading
    import logging
    
    logging.basicConfig()
    
    def loggingThread(clazz, logger):
        class _Thread(clazz):
            def __init__(self, *args, **kwargs):
                clazz.__init__(self, *args, **kwargs)
    
            def run(self):
                try:
                   clazz.run(self)
                except Exception as e:
                    logger.error("%s has Crashed!", self, exc_info=True)
    
        return _Thread
    
    threading.Thread = loggingThread(threading.Thread, logging)
    
    import random 
    
    def ohNo(range1, range2):
        for x in xrange(1, range1):
            if x % random.randint(1, range2) == 0:
                raise ValueError("Oh no. %d is an illeagal value!" % (x,))
    
    test = threading.Thread(target=ohNo, args=(500,100))
    test.start()