Hiển thị theo dõi ngăn xếp từ một ứng dụng Python đang chạy


340

Thỉnh thoảng tôi có ứng dụng Python này bị kẹt và tôi không thể tìm ra nơi nào.

Có cách nào để báo hiệu trình thông dịch Python để hiển thị cho bạn mã chính xác đang chạy không?

Một số loại stacktrace trên bay?

Câu hỏi liên quan:



Câu trả lời:


315

Tôi có mô-đun tôi sử dụng cho các tình huống như thế này - trong đó một quy trình sẽ chạy trong một thời gian dài nhưng đôi khi bị kẹt vì những lý do không xác định và không thể thực hiện được. Nó hơi hack và chỉ hoạt động trên unix (yêu cầu tín hiệu):

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

Để sử dụng, chỉ cần gọi hàm nghe () tại một số điểm khi chương trình của bạn khởi động (Bạn thậm chí có thể dán nó vào trang web.py để tất cả các chương trình python sử dụng nó) và để nó chạy. Tại bất kỳ thời điểm nào, hãy gửi quá trình tín hiệu SIGUSR1, sử dụng kill hoặc trong python:

    os.kill(pid, signal.SIGUSR1)

Điều này sẽ khiến chương trình chuyển sang bảng điều khiển python tại thời điểm hiện tại, hiển thị cho bạn dấu vết ngăn xếp và cho phép bạn thao tác với các biến. Sử dụng control-d (EOF) để tiếp tục chạy (mặc dù lưu ý rằng bạn có thể sẽ làm gián đoạn bất kỳ I / O nào v.v. tại điểm bạn báo hiệu, vì vậy nó không hoàn toàn không xâm phạm.

Tôi có một tập lệnh khác thực hiện điều tương tự, ngoại trừ nó giao tiếp với quy trình đang chạy thông qua một đường ống (để cho phép gỡ lỗi các quy trình nền, v.v.). Nó hơi lớn để đăng ở đây, nhưng tôi đã thêm nó như một công thức nấu ăn trăn .


1
Cảm ơn! Đây chỉ là những gì tôi đang tìm kiếm. Có lẽ bạn cũng có thể đăng tập lệnh đó với sự hỗ trợ của đường ống trên một số trang web đoạn trích Python?
Seb

2
Bây giờ tôi đã đăng nó tại trang web sách nấu ăn python - liên kết được thêm vào.
Brian

1
Tôi cần thêm "đường dẫn nhập" để bật các tính năng lịch sử.
miracle2k

2
Mẹo tuyệt vời! Điều này cũng hoạt động để gửi tín hiệu, đến tất cả các quy trình có chứa từ "mypythonapp": pkill -SIGUSR1 -f mypythonapp
Alexander

10
Nếu ứng dụng bị kẹt, vòng lặp trình thông dịch Python có thể không chạy được để xử lý tín hiệu. Sử dụng faulthandlermô-đun (và cổng sau của nó được tìm thấy trên PyPI) cho trình xử lý tín hiệu mức C sẽ in ngăn xếp Python mà không yêu cầu vòng lặp trình thông dịch phải phản hồi.
gps

146

Đề xuất để cài đặt một trình xử lý tín hiệu là một điều tốt, và tôi sử dụng nó rất nhiều. Ví dụ, bzr theo mặc định sẽ cài đặt trình xử lý SIGQUIT để gọi pdb.set_trace()ngay lập tức đưa bạn vào dấu nhắc pdb . (Xem nguồn của mô-đun bzrlib.breakin để biết chi tiết chính xác.) Với pdb, bạn không chỉ có thể theo dõi ngăn xếp hiện tại mà còn kiểm tra các biến, v.v.

Tuy nhiên, đôi khi tôi cần gỡ lỗi một quy trình mà tôi không có tầm nhìn xa để cài đặt trình xử lý tín hiệu. Trên linux, bạn có thể đính kèm gdb vào quy trình và lấy dấu vết ngăn xếp python với một số macro gdb. Đặt http://svn.python.org/projects/python/trunk/Misc/gdbinit vào ~/.gdbinit, sau đó:

  • Đính kèm gdb: gdb -p PID
  • Lấy dấu vết ngăn xếp python: pystack

Thật không may, nó không hoàn toàn đáng tin cậy, nhưng nó hoạt động hầu hết thời gian.

Cuối cùng, việc đính kèm stracethường có thể cho bạn ý tưởng tốt về quy trình đang làm.


2
Xuất sắc! Lệnh pystack đôi khi bị khóa, nhưng trước khi nó thực hiện cho tôi một dấu vết ngăn xếp hoàn chỉnh của quá trình, trong các dòng mã python, mà không cần phải thực hiện bất kỳ sự chuẩn bị nào.
muudscope

26
Cập nhật nhỏ: kỹ thuật gdb này (và mã cập nhật) được ghi lại tại wiki.python.org/moin/DebuggingWithGdb Có một số phát triển trên mặt trận này, được ghi lại tại URL đó và rõ ràng gdb 7 có hỗ trợ Python.
Nelson

7
Theo như tôi có thể nói, điều này chỉ thực sự hoạt động nếu bạn có các biểu tượng gỡ lỗi được biên dịch thành nhị phân python của bạn - ví dụ: bạn đã chạy chương trình của mình với python2-dbg (trên Ubuntu, đây là một gói riêng python-dbg). Không có những biểu tượng đó, bạn dường như không nhận được nhiều thông tin hữu ích.
drevicko

1
trong trường hợp của tôi, điều này trở lại Unable to locate python framevới mỗi lệnh
seriyPS

6
gdb 7+ - với sự hỗ trợ của python được cung cấp bởi python-gdb.py. Thêm chi tiết tại đây: chezsoi.org/lucas/blog/2014/11/07/en-gdb-python-macros
Lucas Cimon

71

Tôi hầu như luôn luôn xử lý nhiều luồng và luồng chính thường không hoạt động nhiều, vì vậy điều thú vị nhất là kết xuất tất cả các ngăn xếp (giống như kết xuất của Java). Đây là một triển khai dựa trên blog này :

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)

53

Bắt một dấu vết ngăn xếp của một chương trình python chưa chuẩn bị , chạy trong một python stock mà không cần gỡ lỗi các biểu tượng có thể được thực hiện với pyrasite . Làm việc như một cơ duyên đối với tôi trong 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

(Hat tip cho @Albert, người có câu trả lời chứa con trỏ tới cái này, trong số các công cụ khác.)


5
Điều này làm việc rất tốt cho tôi, nơi dump_stacks.pyđơn giản làimport traceback; traceback.print_stack()
John Lehmann

2
traceback -lcung cấp cho bạn một danh sách các kịch bản python được xác định trước mà bạn có thể sử dụng và dump_stacks.pylà một trong số chúng. Nếu bạn đang sử dụng của riêng bạn (ví dụ để viết theo dõi ngăn xếp vào một tệp), có thể là khôn ngoan khi sử dụng một tên khác.
johndodo

12
Mẹo quan trọng: chạy apt-get install gdb python-dbg(hoặc tương đương) trước khi chạy pyrasite, nếu không nó sẽ âm thầm thất bại. Hoạt động như một sự quyến rũ khác!
johndodo

Lần phát hành cuối cùng của pyrasite là vào năm 2012
Boris

35
>>> import traceback
>>> def x():
>>>    print traceback.extract_stack()

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

Bạn cũng có thể định dạng độc đáo theo dõi ngăn xếp, xem tài liệu .

Chỉnh sửa : Để mô phỏng hành vi của Java, như được đề xuất bởi @Doumund Leeder, hãy thêm điều này:

import signal
import traceback

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

mã khởi động trong ứng dụng của bạn. Sau đó, bạn có thể in ngăn xếp bằng cách gửi SIGUSR1đến quy trình Python đang chạy.


2
Điều này sẽ chỉ in backtrace của chủ đề chính. Tôi vẫn chưa tìm thấy một giải pháp để xem dấu vết cho tất cả các chủ đề. Trong thực tế, python dường như thiếu API để lấy stack từ đối tượng Thread, mặc dù threading.enum Cả () cho phép truy cập vào tất cả các đối tượng Thread.
haridsv

Điều này hoạt động tuyệt vời trên cygwin. Mặc dù vậy, nó chỉ in ba dòng dấu vết ngăn xếp, nhưng thế là đủ để có được manh mối
slashdottir

28

Các traceback mô-đun có một số chức năng tốt đẹp, trong đó có: print_stack:

import traceback

traceback.print_stack()

1
Để viết ra dấu vết ngăn xếp vào một tệp, hãy sử dụng: import traceback; f = open('/tmp/stack-trace.log', 'w') traceback.print_stack(file=f) f.close()
GuruM

1
+1 vào @gulgi để trả lời dễ sử dụng. Một số câu trả lời khác có vẻ rất phức tạp đối với nhiệm vụ đơn giản của tôi là lấy dấu vết ngăn xếp cuộc gọi từ chức năng của tập lệnh.
Giáo sư

24

Bạn có thể thử mô-đun errorhandler . Cài đặt nó bằng cách sử dụng pip install faulthandlervà thêm:

import faulthandler, signal
faulthandler.register(signal.SIGUSR1)

vào đầu chương trình của bạn. Sau đó gửi SIGUSR1 đến tiến trình của bạn (ví dụ kill -USR1 42:) để hiển thị truy nguyên Python của tất cả các luồng cho đầu ra tiêu chuẩn. Đọc tài liệu để có thêm tùy chọn (ví dụ: đăng nhập vào một tệp) và các cách khác để hiển thị truy nguyên.

Mô-đun này là một phần của Python 3.3. Đối với Python 2, xem http://faulthandler.readthedocs.org/


20

Điều thực sự giúp tôi ở đây là mẹo của spiv (mà tôi sẽ bỏ phiếu và nhận xét nếu tôi có điểm danh tiếng) để có được một dấu vết ngăn xếp trong quá trình Python chưa chuẩn bị . Ngoại trừ nó không hoạt động cho đến khi tôi sửa đổi tập lệnh gdbinit . Vì thế:

  • tải xuống http://svn.python.org/projects/python/trunk/Misc/gdbinit và đặt nó vào~/.gdbinit

  • chỉnh sửa nó, thay đổi PyEval_EvalFramethànhPyEval_EvalFrameEx[chỉnh sửa: không còn cần thiết; tệp được liên kết đã có thay đổi này kể từ 2010-01-14]

  • Đính kèm gdb: gdb -p PID

  • Lấy dấu vết ngăn xếp python: pystack


Các gdbinit tại URL được đề cập dường như đã có bản vá mà bạn đề xuất. Trong trường hợp của tôi, khi tôi gõ pystack, CPU của tôi bị treo. Không chắc chắn lý do tại sao.
Jesse Glick

2
Không, nó không - tôi không rõ, xin lỗi, vì dòng đó xuất hiện ở ba nơi. Bản vá tôi liên kết để hiển thị cái nào tôi đã thay đổi khi tôi thấy tác phẩm này.
Gunnlaugur Briem

2
Giống như câu trả lời của @ spiv, điều này đòi hỏi chương trình phải chạy theo python được biên dịch với các biểu tượng gỡ lỗi. Nếu không, bạn sẽ nhận đượcNo symbol "co" in current context.
Nickolay

12

Tôi sẽ thêm điều này như một bình luận cho phản hồi của haridsv , nhưng tôi thiếu danh tiếng để làm như vậy:

Một số người trong chúng ta vẫn bị mắc kẹt trên một phiên bản Python cũ hơn 2.6 (bắt buộc cho Thread.ident), vì vậy tôi đã nhận được mã làm việc trong Python 2.5 (mặc dù không có tên luồng được hiển thị) như vậy:

import traceback
import sys
def dumpstacks(signal, frame):
    code = []
    for threadId, stack in sys._current_frames().items():
            code.append("\n# Thread: %d" % (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)

11

python -dv yourcript.py

Điều đó sẽ làm cho trình thông dịch chạy trong chế độ gỡ lỗi và cung cấp cho bạn một dấu vết về những gì trình thông dịch đang làm.

Nếu bạn muốn gỡ lỗi tương tác mã, bạn nên chạy nó như thế này:

python -m pdb của bạn

Điều đó nói cho trình thông dịch python chạy tập lệnh của bạn với mô-đun "pdb", đó là trình gỡ lỗi python, nếu bạn chạy nó như thế thì trình thông dịch sẽ được thực thi trong chế độ tương tác, giống như GDB


Điều này không trả lời câu hỏi. Câu hỏi là về một quá trình đã chạy.
dbn

11

Hãy xem faulthandlermô-đun, mới trong Python 3.3. Một faulthandlerbackport để sử dụng trong Python 2 có sẵn trên PyPI.


2
Một câu trả lời gần đây hơn của @haypo bao gồm điều này chi tiết hơn. Tôi không chắc cách này thường được xử lý trên SO, nhưng cảm thấy sai khi có hai câu trả lời cơ bản trùng lặp ...
Nickolay

7

Trên Solaris, bạn có thể sử dụng pstack (1) Không cần thay đổi mã python. ví dụ.

# pstack 16000 | grep : | head
16000: /usr/bin/python2.6 /usr/lib/pkg.depotd --cfg svc:/application/pkg/serv
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:282 (_wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:295 (wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:242 (block) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/_init_.py:249 (quickstart) ]
[ /usr/lib/pkg.depotd:890 (<module>) ]
[ /usr/lib/python2.6/threading.py:256 (wait) ]
[ /usr/lib/python2.6/Queue.py:177 (get) ]
[ /usr/lib/python2.6/vendor-packages/pkg/server/depot.py:2142 (run) ]
[ /usr/lib/python2.6/threading.py:477 (run)
etc.

2
Dường như có một chương trình Debian / Ubuntu pstackthực hiện điều tương tự
Rory

1
Nó dường như chỉ cung cấp backtrace trong linux, không phải là truy nguyên Python với tên tệp và số dòng.
ogrisel

6

Nếu bạn đang sử dụng hệ thống Linux, hãy sử dụng các gdbphần mở rộng gỡ lỗi của Python (có thể ở trong python-dbghoặc python-debuginfogói). Nó cũng giúp với các ứng dụng đa luồng, ứng dụng GUI và mô-đun C.

Chạy chương trình của bạn với:

$ gdb -ex r --args python <programname>.py [arguments]

Điều này hướng dẫn gdbđể chuẩn bị python <programname>.py <arguments>run nó.

Bây giờ khi bạn lập trình bị treo, hãy chuyển sang gdbbàn điều khiển, nhấn Ctr+Cvà thực hiện:

(gdb) thread apply all py-list

Xem phiên ví dụ và thêm thông tin ở đâyở đây .


6

Tôi đã tìm kiếm một giải pháp để gỡ lỗi các chủ đề của mình và tôi đã tìm thấy nó ở đây nhờ haridsv. Tôi sử dụng phiên bản đơn giản hóa một chút bằng cách sử dụng tracBack.print_stack ():

import sys, traceback, signal
import threading
import os

def dumpstacks(signal, frame):
  id2name = dict((th.ident, th.name) for th in threading.enumerate())
  for threadId, stack in sys._current_frames().items():
    print(id2name[threadId])
    traceback.print_stack(f=stack)

signal.signal(signal.SIGQUIT, dumpstacks)

os.killpg(os.getpgid(0), signal.SIGQUIT)

Đối với nhu cầu của tôi, tôi cũng lọc chủ đề theo tên.


3

Thật đáng để xem xét Pydb , "một phiên bản mở rộng của trình gỡ lỗi Python lỏng lẻo dựa trên tập lệnh gdb". Nó bao gồm các trình quản lý tín hiệu có thể đảm nhiệm việc khởi động trình gỡ lỗi khi tín hiệu được chỉ định được gửi.

Một dự án Summer of Code năm 2006 đã xem xét việc thêm các tính năng sửa lỗi từ xa vào pydb trong một mô-đun gọi là mpdb .


Có vẻ như nó đã trải qua hai ( 1 ) lần viết lại ( 2 ) mà không cần thêm tính năng đính kèm mà tôi đang tìm kiếm ...
Nickolay

3

Tôi đã hack cùng một số công cụ gắn vào một quy trình Python đang chạy và tiêm một số mã để lấy shell Python.

Xem tại đây: https://github.com/albertz/pydbattach


1
Lưu ý: không rõ ràng làm thế nào để xây dựng này. Cảm ơn các liên kết bạn đã đặt trong README: pyrasitehoạt động hoàn hảo!
Nickolay

3

Nó có thể được thực hiện với py-spy tuyệt vời . Đây là một trình lược tả mẫu cho các chương trình Python , vì vậy công việc của nó là gắn vào các quy trình Python và lấy mẫu các ngăn xếp cuộc gọi của chúng. Do đó, py-spy dump --pid $SOME_PIDlà tất cả những gì bạn cần làm để loại bỏ ngăn xếp cuộc gọi của tất cả các luồng trong $SOME_PIDquy trình. Thông thường, nó cần các đặc quyền leo thang (để đọc bộ nhớ của quá trình đích).

Đây là một ví dụ về giao diện của ứng dụng Python theo luồng.

$ sudo py-spy dump --pid 31080
Process 31080: python3.7 -m chronologer -e production serve -u www-data -m
Python v3.7.1 (/usr/local/bin/python3.7)

Thread 0x7FEF5E410400 (active): "MainThread"
    _wait (cherrypy/process/wspbus.py:370)
    wait (cherrypy/process/wspbus.py:384)
    block (cherrypy/process/wspbus.py:321)
    start (cherrypy/daemon.py:72)
    serve (chronologer/cli.py:27)
    main (chronologer/cli.py:84)
    <module> (chronologer/__main__.py:5)
    _run_code (runpy.py:85)
    _run_module_as_main (runpy.py:193)
Thread 0x7FEF55636700 (active): "_TimeoutMonitor"
    run (cherrypy/process/plugins.py:518)
    _bootstrap_inner (threading.py:917)
    _bootstrap (threading.py:885)
Thread 0x7FEF54B35700 (active): "HTTPServer Thread-2"
    accept (socket.py:212)
    tick (cherrypy/wsgiserver/__init__.py:2075)
    start (cherrypy/wsgiserver/__init__.py:2021)
    _start_http_thread (cherrypy/process/servers.py:217)
    run (threading.py:865)
    _bootstrap_inner (threading.py:917)
    _bootstrap (threading.py:885)
...
Thread 0x7FEF2BFFF700 (idle): "CP Server Thread-10"
    wait (threading.py:296)
    get (queue.py:170)
    run (cherrypy/wsgiserver/__init__.py:1586)
    _bootstrap_inner (threading.py:917)
    _bootstrap (threading.py:885)  

2

pyenses là một trình gỡ lỗi có thể tương tác với việc chạy các quy trình python, in dấu vết ngăn xếp, các biến, v.v. mà không cần bất kỳ thiết lập tiên nghiệm nào.

Mặc dù trước đây tôi thường sử dụng giải pháp xử lý tín hiệu, nhưng vẫn có thể khó tái tạo vấn đề trong một số môi trường nhất định.


3
Rõ ràng là nó không tương thích với các bản dựng gdb nhất định (ví dụ: bản dựng tôi đã cài đặt trên ubfox): github.com/google/pyenses/issues/16 , yêu cầu xây dựng lại theo cách thủ công. Một trình sửa lỗi khác pyrasite, làm việc như một cơ duyên đối với tôi.
Nickolay

1

Không có cách nào để nối vào một quy trình python đang chạy và nhận được kết quả hợp lý. Những gì tôi làm nếu các quy trình bị khóa là nối chuỗi và cố gắng tìm hiểu chính xác những gì đang xảy ra.

Thật không may, strace thường là người quan sát "sửa chữa" các điều kiện cuộc đua để đầu ra cũng vô dụng ở đó.


1
Vâng, đây là sự thật. Thật là xấu hổ mặc dù thdb pdb không hỗ trợ gắn vào một quy trình đang chạy ...
Bartosz Radaczyński

Đây không phải là sự thật. Xem câu trả lời bằng "spiv" ở trên, trong đó cho thấy cách kết nối gdb và nhận dấu vết ngăn xếp Python.
rút cooke

Điều này không giống nhau - các macro gdb đó không đáng tin cậy và không cung cấp toàn bộ giao diện / sức mạnh quen thuộc của pdb. Tôi thường ước ai đó đã viết một ứng dụng nhỏ sẽ sử dụng ptrace để đưa một số mã byte Python vào một quy trình Python đang chạy và để nó thực thi 'import pdb; pdb.set_trace () ', cũng có thể sau khi tạm thời chuyển hướng sys.stdin / stdout.
Marius Gedminas

Điều này không còn đúng nữa, hãy xem các câu trả lời khác chỉ vào pyring / pyrasite.
Nickolay

1

Bạn có thể sử dụng PuDB , trình gỡ lỗi Python có giao diện nguyền rủa để làm điều này. Chỉ cần thêm

from pudb import set_interrupt_handler; set_interrupt_handler()

mã của bạn và sử dụng Ctrl-C khi bạn muốn phá vỡ. Bạn có thể tiếp tục cvà phá vỡ lại nhiều lần nếu bạn bỏ lỡ nó và muốn thử lại.


Khi bạn sử dụng lệnh trên trong django, đừng quên chạy máy chủ đúng cách để tránh sự cố: "Manage.txt ranerver --noreload --nothreading"
potar 13/215

1

Tôi đang ở trong trại GDB với phần mở rộng python. Theo dõi https://wiki.python.org/moin/DebuggingWithGdb , có nghĩa là

  1. dnf install gdb python-debuginfo hoặc là sudo apt-get install gdb python2.7-dbg
  2. gdb python <pid of running process>
  3. py-bt

Cũng xem xét info threadsthread apply all py-bt.


Có bình thường để nhận được phản hồi như Traceback (most recent call first): Python Exception <class 'gdb.error'> No frame is currently selected.: Error occurred in Python command: No frame is currently selected.khi chạy py-btvào gdbkhông?
xiêu vẹo

1
đừng bận tâm. đó là vì ứng dụng của tôi được chạy như sudo. tôi cũng cần phải chạy gdb pyton <pid>như sudo.
xiêu vẹo

1

Cách gỡ lỗi bất kỳ chức năng nào trong bảng điều khiển :

Tạo hàm nơi bạn sử dụng pdb.set_trace () , sau đó là hàm bạn muốn gỡ lỗi.

>>> import pdb
>>> import my_function

>>> def f():
...     pdb.set_trace()
...     my_function()
... 

Sau đó gọi hàm đã tạo:

>>> f()
> <stdin>(3)f()
(Pdb) s
--Call--
> <stdin>(1)my_function()
(Pdb) 

Chúc mừng gỡ lỗi :)


0

Tôi không biết bất cứ điều gì tương tự như phản hồi của java đối với SIGQUIT , vì vậy bạn có thể phải xây dựng nó vào ứng dụng của mình. Có lẽ bạn có thể tạo một máy chủ trong một luồng khác có thể nhận được một stacktrace khi phản hồi một tin nhắn nào đó?


0

sử dụng mô đun kiểm tra.

nhập kiểm tra trợ giúp (tests.stack) Trợ giúp về ngăn xếp chức năng trong kiểm tra mô-đun:

ngăn xếp (bối cảnh = 1) Trả về danh sách các bản ghi cho ngăn xếp phía trên khung của trình gọi.

Tôi thấy nó thực sự hữu ích.


0

Trong Python 3, pdb sẽ tự động cài đặt trình xử lý tín hiệu vào lần đầu tiên bạn sử dụng c (ont (inue)) trong trình gỡ lỗi. Nhấn Control-C sau đó sẽ đưa bạn trở lại ngay tại đó. Trong Python 2, đây là một lớp lót nên hoạt động ngay cả trong các phiên bản tương đối cũ (đã được thử nghiệm trong 2.7 nhưng tôi đã kiểm tra nguồn Python trở lại 2.4 và nó có vẻ ổn):

import pdb, signal
signal.signal(signal.SIGINT, lambda sig, frame: pdb.Pdb().set_trace(frame))

pdb đáng để học hỏi nếu bạn dành bất kỳ khoảng thời gian nào để gỡ lỗi Python. Giao diện hơi khó hiểu nhưng nên quen thuộc với bất kỳ ai đã sử dụng các công cụ tương tự, chẳng hạn như gdb.


0

Trong trường hợp bạn cần thực hiện việc này với uWSGI, nó có Python Tracebacker tích hợp và vấn đề là cho phép nó trong cấu hình (số được gắn vào tên cho mỗi nhân viên):

py-tracebacker=/var/run/uwsgi/pytrace

Khi bạn đã hoàn thành việc này, bạn có thể in backtrace chỉ bằng cách kết nối với ổ cắm:

uwsgi --connect-and-read /var/run/uwsgi/pytrace1

0

Tại điểm mã được chạy, bạn có thể chèn đoạn mã nhỏ này để xem dấu vết ngăn xếp được in được định dạng độc đáo. Nó giả định rằng bạn có một thư mục được gọi logstại thư mục gốc của dự án.

# DEBUG: START DEBUG -->
import traceback

with open('logs/stack-trace.log', 'w') as file:
    traceback.print_stack(file=file)
# DEBUG: END DEBUG --!
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.