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

时间:2018-08-14 14:37:08

标签: python linux multithreading python-2.7 stack-trace

问题

我有一个必须使用的库,它是用Python 2.7编写的。其中存在多个错误,其中一个错误有时会导致调用线程崩溃(但是很少)。我想生成堆栈跟踪,以便可以确定库崩溃时哪个线程快死了。我将遗失的跟踪记录转储到STDERR,即:

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(因此我可以附加到正在运行的Python应用程序)。但是,我看不到与(现在已死)线程相关的任何有用信息。


问题

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

谢谢。

1 个答案:

答案 0 :(得分:1)

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

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()