Показ отслеживания стека от запуска приложение Python

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

330
задан Community 23 May 2017 в 00:31
поделиться

11 ответов

У меня есть модуль, который я использую для таких ситуаций - куда процесс будет работать в течение долгого времени, но иногда застревает по неизвестным и невоспроизводимым причинам. Это - немного hacky, и только работает над Unix (требует сигналов):

import code, traceback, signal

def debug(sig, frame):
    """Interrupt running process, and provide a python prompt for
    interactive debugging."""
    d={'_frame':frame}         # Allow access to frame object.
    d.update(frame.f_globals)  # Unless shadowed by global
    d.update(frame.f_locals)

    i = code.InteractiveConsole(d)
    message  = "Signal received : entering python shell.\nTraceback:\n"
    message += ''.join(traceback.format_stack(frame))
    i.interact(message)

def listen():
    signal.signal(signal.SIGUSR1, debug)  # Register handler

Для использования просто назовите слушать () функция в какой-то момент, когда программа запускает (Вы могли даже придерживаться, это в site.py для имения всех программ Python использует его), и позвольте ему работать. В любой точке отправьте процессу сигнал SIGUSR1, использование уничтожает, или в Python:

    os.kill(pid, signal.SIGUSR1)

Это заставит программу повреждаться к консоли Python в точке, в которой это в настоящее время, показывая Вам отслеживание стека и разрешение Вам управлять переменными. Используйте управление-d (EOF), чтобы продолжить работать (хотя примечание, что Вы, вероятно, прервете любой ввод-вывод и т.д. в точке, о которой Вы предупреждаете, таким образом, это не полностью ненавязчиво.

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

поваренной книги Python
306
ответ дан Mike Morearty 23 November 2019 в 00:46
поделиться

Предложение для установки обработчика сигналов является хорошим, и я использую его много. Например, bzr значением по умолчанию устанавливает обработчик SIGQUIT, который вызывает pdb.set_trace() для непосредственного бросания Вас в подсказка pdb. (См. источник bzrlib.breakin модуля для точных деталей.) С pdb можно не только получить текущее отслеживание стека, но также и осмотреть переменные, и т.д.

Однако иногда я должен отладить процесс, в котором у меня не было предвидения для установки обработчика сигналов. На Linux можно присоединить gdb к процессу и получить отслеживание стека Python с некоторыми gdb макросами. Помещенный http://svn.python.org/projects/python/trunk/Misc/gdbinit в ~/.gdbinit, тогда:

  • Присоединение gdb: gdb -p PID
  • Получают отслеживание стека Python: pystack

Это не полностью надежно, к сожалению, но это работает большую часть времени.

Наконец, присоединяя strace может часто давать Вам хорошую идею, что делает процесс.

144
ответ дан Mr. Deathless 23 November 2019 в 00:46
поделиться

Я не знаю ни о чем подобном ответ Java на SIGQUIT, таким образом, Вам, возможно, придется создать его в к Вашему приложению. Возможно, Вы могли сделать сервер в другом потоке, который может получить stacktrace на ответе на сообщение некоторого вида?

0
ответ дан Douglas Leeder 23 November 2019 в 00:46
поделиться

Нет никакого способа сцепиться в под управлением Python, обрабатывают и получают разумные результаты. То, что я делаю, если процессы запираются, сцепляет strace в и пытается выяснить то, что точно происходит.

, К сожалению, часто strace является наблюдателем, который "фиксирует" условия состязания так, чтобы вывод был бесполезен там также.

1
ответ дан Armin Ronacher 23 November 2019 в 00:46
поделиться

На это стоит посмотреть Pydb, "расширенная версия отладчика Python свободно на основе gdb набора команд". Это включает менеджеров по сигналу, которые могут заботиться о запуске отладчика, когда указанный сигнал отправляется.

Лето А 2006 года проекта Кода, на который посмотрели, добавляя удаленные функции отладки к pydb в модуле, названном mpdb.

3
ответ дан rcoup 23 November 2019 в 00:46
поделиться

python-dv yourscript.py

, Который сделает интерпретатор, чтобы работать в режиме отладки и дать Вам трассировку того, что делает интерпретатор.

, Если Вы хотите в интерактивном режиме отладить код, необходимо выполнить его как это:

python-m pdb yourscript.py

, Который говорит интерпретатору Python выполнять Ваш сценарий с модулем "pdb", который является отладчиком Python при выполнении его как этот интерпретатор будет выполняться в интерактивном режиме, во многом как GDB

11
ответ дан Gustavo Rubio 23 November 2019 в 00:46
поделиться

Что действительно помогло мне, вот подсказка темной личности (который я проголосовал бы и комментарий, если бы у меня были точки репутации) для того, чтобы вытащить отслеживание стека из неподготовленный процесс Python. Кроме него не работал, пока я не изменил gdbinit сценарий . Так:

  • загрузка http://svn.python.org/projects/python/trunk/Misc/gdbinit и помещенный это в ~/.gdbinit

  • редактирует его, изменяясь PyEval_EvalFrame к PyEval_EvalFrameEx [редактирование: больше необходимый; связанный файл уже имеет это изменение с 14.01.2010]

  • Присоединение gdb: gdb -p PID

  • Получают отслеживание стека Python: pystack

20
ответ дан Community 23 November 2019 в 00:46
поделиться

модуль traceback имеет некоторые хорошие функции среди них: print_stack:

import traceback

traceback.print_stack()
27
ответ дан gulgi 23 November 2019 в 00:46
поделиться
>>> import traceback
>>> def x():
>>>    print traceback.extract_stack()

>>> x()
[('<stdin>', 1, '<module>', None), ('<stdin>', 2, 'x', None)]

можно также приятно отформатировать отслеживание стека, видеть эти документы .

Редактирование : Для моделирования поведения Java, как предложено @Douglas Leeder, добавляет, это:

import signal
import traceback

signal.signal(signal.SIGUSR1, lambda sig, stack: traceback.print_stack(stack))

к запуску кодируют в Вашем приложении. Тогда можно распечатать стек путем отправки SIGUSR1 к рабочему процессу Python.

35
ответ дан Torsten Marek 23 November 2019 в 00:46
поделиться

Я почти всегда имею дело с несколькими потоками, а основной поток, как правило, мало что делает, поэтому наиболее интересно выгрузить все стеки ( что больше похоже на дамп Java). Вот реализация на основе этого блога :

import threading, sys, traceback

def dumpstacks(signal, frame):
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
    code = []
    for threadId, stack in sys._current_frames().items():
        code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), 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()))
    print "\n".join(code)

import signal
signal.signal(signal.SIGQUIT, dumpstacks)
71
ответ дан 23 November 2019 в 00:46
поделиться

использовать модуль inspect.

import inspect помощь (inspect.stack) Справка по стеку функций в модуле inspect:

stack (context = 1) Вернуть список записей для стека над кадром вызывающего.

Я считаю это действительно очень полезным.

0
ответ дан 23 November 2019 в 00:46
поделиться
Другие вопросы по тегам:

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