Вопрос по multithreading, python – Дамп стека следов всех активных потоков

28

Я пытаюсь вывести список всех активных потоков, включая текущий стек каждого из них. Я могу получить список всех потоков, используя threading.enumerate (), но я не могу найти способ добраться до стека оттуда.

Предыстория: приложение Zope / Plone сходит с ума время от времени, потребляя 100% процессорного времени и нуждается в перезапуске. У меня есть ощущение, что это цикл, который не завершается должным образом, но я не могу воспроизвести его в test-environemt для проверки. Мне удалось зарегистрировать обработчик сигнала, который может быть запущен извне, так что я могу вызвать некоторый код, как только ситуация повторяется. Если бы я мог сбросить трассировку стека для всех активных потоков, это дало бы мне понять, что идет не так. Дырочка работает на питоне 2.4 ...

Любые идеи о том, как отследить подобные ситуации, приветствуются :)

Ура,    Chriss

Ваш Ответ

6   ответов
18

Для Python 3.3 и выше, естьfaulthandler.dump_traceback().

Приведенный ниже код производит аналогичные выходные данные, но включает имя потока и может быть расширен для печати дополнительной информации.

for th in threading.enumerate():
    print(th)
    traceback.print_stack(sys._current_frames()[th.ident])
    print()
39

Как указывает джиттер в предыдущем ответеsys._current_frames() дает вам то, что вам нужно для v2.5 +. Для ленивых следующий фрагмент кода работал для меня и может помочь вам:

print >> sys.stderr, "\n*** STACKTRACE - START ***\n"
code = []
for threadId, stack in sys._current_frames().items():
    code.append("\n# ThreadID: %s" % threadId)
    for filename, lineno, name, line in traceback.extract_stack(stack):
        code.append('File: "%s", line %d, in %s' % (filename,
                                                    lineno, name))
        if line:
            code.append("  %s" % (line.strip()))

for line in code:
    print >> sys.stderr, line
print >> sys.stderr, "\n*** STACKTRACE - END ***\n"
7

2,4. Очень плохо. С Python 2.5 естьsys._current_frames().

Но вы могли бы попробоватьthreadframe, И если makefile доставляет вам неприятности, вы можете попробовать этоsetup.py для потокового кадра

Пример вывода при использовании потокового кадра

0

Существует соответствующий рецепт наASPN, Ты можешь использоватьthreading.enumerate() чтобы получить все приливы, просто вызовите _async_raise () с некоторым подходящим исключением, чтобы вызвать трассировку стека.

1

Просто ради полноты,Products.LongRequestLogger супер полезно для выявления узких мест, и для этого он сбрасывает трассировки стека через определенные промежутки времени.

10

При использовании Zope вы хотите установитьProducts.signalstack или жеMr.Freeze; они были разработаны именно для этой цели!

Отправьте сигнал USR1 на ваш сервер Zope, и он немедленно сбросит следы стека для всех потоков на консоль. Он будет делать это, даже если все потоки Zope заблокированы.

Под капотом эти пакеты косвенно используютthreadframes; для Python версии 2.5 и выше, когдаnot используя Zope, вы можете создать ту же функциональность, используяsys._current_frames() функция для доступа к кадрам стека для каждого потока.

По состоянию наZope 2.12.5 эта функциональность встроена в сам Zope, и больше нет необходимости устанавливать дополнительные пакеты.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Chriss
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededstackoverflow.com/a/36633215/3046069
Error: User Rate Limit Exceededsys._current_frames().

Похожие вопросы