때때로이 파이썬 응용 프로그램이 붙어있어 어디에서 찾을 수 없습니다.
실행중인 정확한 코드를 보여주기 위해 Python 인터프리터에게 신호를 보내는 방법이 있습니까?
어떤 종류의 즉석 스택 트레이스?
관련 질문 :
답변
프로세스가 오랜 시간 동안 실행되지만 알 수없고 재현 할 수없는 이유로 때때로 멈추는 상황과 같은 상황에서 사용하는 모듈이 있습니다. 약간 해키이며 유닉스에서만 작동합니다 (신호 필요).
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
사용하려면 프로그램이 시작될 때 어느 시점에서 listen () 함수를 호출하십시오 (site.py에서 모든 파이썬 프로그램에서 사용하도록 할 수도 있습니다). 언제든지 kill을 사용하여 또는 파이썬으로 프로세스에 SIGUSR1 신호를 보냅니다.
os.kill(pid, signal.SIGUSR1)
이로 인해 프로그램이 현재있는 시점에서 파이썬 콘솔에 침입하여 스택 추적을 표시하고 변수를 조작 할 수 있습니다. control-d (EOF)를 사용하여 계속 실행합니다 (신호를 보내는 지점에서 I / O 등을 중단 할 수 있으므로 완전히 방해되지는 않습니다).
파이프를 통해 실행중인 프로세스와 통신하는 것을 제외하고 (백그라운드 프로세스 디버깅 등을 허용하는) 것을 제외하고 동일한 작업을 수행하는 또 다른 스크립트가 있습니다. 여기에 게시하기에는 약간 크지 만 파이썬 요리 책 레시피 로 추가했습니다 .
답변
신호 처리기를 설치하라는 제안은 좋은 것이며 많이 사용합니다. 예를 들어, bzr 은 기본적으로 SIGQUIT 핸들러를 설치 pdb.set_trace()
하여 즉시 pdb 프롬프트 에 놓도록 합니다. (자세한 내용은 bzrlib.breakin 모듈의 소스를 참조하십시오.) pdb를 사용하면 현재 스택 추적뿐만 아니라 변수 등도 검사 할 수 있습니다.
그러나 때로는 신호 처리기를 설치할 예측이없는 프로세스를 디버깅해야합니다. Linux에서는 gdb를 프로세스에 연결하고 일부 gdb 매크로로 파이썬 스택 추적을 얻을 수 있습니다. http://svn.python.org/projects/python/trunk/Misc/gdbinit를 에 넣고 ~/.gdbinit
다음을 수행하십시오.
- gdb 첨부 :
gdb -p
PID
- 파이썬 스택 추적을 가져옵니다.
pystack
불행히도 완전히 신뢰할 만하지는 않지만 대부분의 경우 작동합니다.
마지막으로, 첨부 strace
는 프로세스가 수행하는 작업에 대한 좋은 아이디어를 제공 할 수 있습니다.
답변
나는 거의 항상 여러 스레드를 다루고 있으며 주요 스레드는 일반적으로 많은 일을하지 않으므로 가장 흥미로운 것은 모든 스택을 덤프하는 것입니다 (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)
답변
기호를 디버깅하지 않고 스톡 파이썬에서 실행 되는 준비되지 않은 파이썬 프로그램 의 스택 추적을 얻는 것은 pyrasite를 사용 하여 수행 할 수 있습니다 . Ubuntu Trusty에서 나를 위해 매력처럼 일했습니다.
$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
$ sudo pyrasite 16262 dump_stacks.py # dumps stacks to stdout/stderr of the python program
(@Albert의 팁은 다른 도구 중에서도 이에 대한 포인터가 포함되어 있습니다.)
답변
>>> import traceback
>>> def x():
>>> print traceback.extract_stack()
>>> x()
[('<stdin>', 1, '<module>', None), ('<stdin>', 2, 'x', None)]
스택 추적을 멋지게 포맷 할 수도 있습니다. 문서를 참조하십시오. .
편집 : @Douglas Leeder가 제안한대로 Java의 동작을 시뮬레이션하려면 다음을 추가하십시오.
import signal
import traceback
signal.signal(signal.SIGUSR1, lambda sig, stack: traceback.print_stack(stack))
응용 프로그램의 시작 코드에. 그런 다음 SIGUSR1
실행중인 Python 프로세스 로 보내 스택을 인쇄 할 수 있습니다 .
답변
역 추적 모듈은 그 중 몇 가지 멋진 기능을 가지고 있습니다 : print_stack를 :
import traceback
traceback.print_stack()
답변
결함 핸들러 모듈을 시도 할 수 있습니다 . 다음을 사용하여 설치 pip install faulthandler
하고 추가하십시오.
import faulthandler, signal
faulthandler.register(signal.SIGUSR1)
프로그램 시작시. 그런 다음 SIGUSR1을 프로세스 (ex :)로 보내 kill -USR1 42
모든 스레드의 Python 추적을 표준 출력에 표시하십시오. 설명서를 읽으십시오추가 옵션 (예 : 파일에 로그인) 및 역 추적을 표시하는 다른 방법에 를 .
이 모듈은 이제 Python 3.3의 일부입니다. Python 2의 경우 http://faulthandler.readthedocs.org/를 참조 하십시오.