faulthandler --- Kết xuất truy nguyên Python¶
Added in version 3.3.
Mô-đun này chứa các hàm để kết xuất các dấu vết Python một cách rõ ràng, khi có lỗi, sau khi hết thời gian chờ hoặc theo tín hiệu của người dùng. Gọi faulthandler.enable() để cài đặt trình xử lý lỗi cho các tín hiệu SIGSEGV, SIGFPE, SIGABRT, SIGBUS và SIGILL. Bạn cũng có thể kích hoạt chúng khi khởi động bằng cách đặt biến môi trường PYTHONFAULTHANDLER hoặc bằng cách sử dụng tùy chọn dòng lệnh -X faulthandler.
Trình xử lý lỗi tương thích với các trình xử lý lỗi hệ thống như Apport hoặc trình xử lý lỗi của Windows. Mô-đun này sử dụng ngăn xếp thay thế cho bộ xử lý tín hiệu nếu chức năng sigaltstack() khả dụng. Điều này cho phép nó loại bỏ truy nguyên ngay cả khi tràn ngăn xếp.
Trình xử lý lỗi được gọi trong các trường hợp nghiêm trọng và do đó chỉ có thể sử dụng các chức năng an toàn tín hiệu (ví dụ: nó không thể phân bổ bộ nhớ trên heap). Do hạn chế này, việc bán phá giá theo dõi là tối thiểu so với các lần truy nguyên thông thường của Python:
Chỉ ASCII được hỗ trợ. Trình xử lý lỗi
backslashreplaceđược sử dụng khi mã hóa.Mỗi chuỗi được giới hạn ở 500 ký tự.
Chỉ có tên tệp, tên hàm và số dòng được hiển thị. (không có mã nguồn)
Nó được giới hạn ở 100 khung hình và 100 chủ đề.
Thứ tự bị đảo ngược: cuộc gọi gần đây nhất được hiển thị trước.
Theo mặc định, truy nguyên Python được ghi vào sys.stderr. Để xem dấu vết, ứng dụng phải được chạy trong thiết bị đầu cuối. Ngoài ra, một tệp nhật ký có thể được chuyển tới faulthandler.enable().
Mô-đun này được triển khai bằng C, do đó, việc truy nguyên có thể bị loại bỏ khi gặp sự cố hoặc khi Python bị bế tắc.
Zz000zz gọi faulthandler.enable() khi khởi động Python.
Xem thêm
Loại bỏ dấu vết¶
- faulthandler.dump_traceback(file=sys.stderr, all_threads=True)¶
Kết xuất dấu vết của tất cả các chủ đề vào file. Nếu all_threads là
False, chỉ kết xuất chuỗi hiện tại.Xem thêm
traceback.print_tb(), có thể được sử dụng để in đối tượng truy nguyên.Thay đổi trong phiên bản 3.5: Đã thêm hỗ trợ để truyền bộ mô tả tệp cho chức năng này.
Đổ ngăn xếp C¶
Added in version 3.14.
- faulthandler.dump_c_stack(file=sys.stderr)¶
Kết xuất dấu vết ngăn xếp C của luồng hiện tại vào file.
Nếu bản dựng Python không hỗ trợ nó hoặc hệ điều hành không cung cấp dấu vết ngăn xếp thì thao tác này sẽ in ra lỗi thay cho ngăn xếp C bị kết xuất.
Khả năng tương thích ngăn xếp C¶
Nếu hệ thống không hỗ trợ backtrace(3) hoặc dladdr1(3) cấp C thì kết xuất ngăn xếp C sẽ không hoạt động. Một lỗi sẽ được in thay vì ngăn xếp.
Ngoài ra, một số trình biên dịch không hỗ trợ triển khai CPython's của các kết xuất ngăn xếp C. Kết quả là một lỗi khác có thể được in thay vì ngăn xếp, ngay cả khi hệ điều hành hỗ trợ đổ ngăn xếp.
Ghi chú
Việc kết xuất ngăn xếp C có thể chậm tùy ý, tùy thuộc vào mức DWARF của các tệp nhị phân trong ngăn xếp cuộc gọi.
Trạng thái xử lý lỗi¶
- faulthandler.enable(file=sys.stderr, all_threads=True, c_stack=True)¶
Kích hoạt trình xử lý lỗi: cài đặt trình xử lý cho các tín hiệu
SIGSEGV,SIGFPE,SIGABRT,SIGBUSvàSIGILLđể loại bỏ dấu vết Python. Nếu all_threads làTrue, hãy tạo dấu vết cho mọi luồng đang chạy. Nếu không, chỉ kết xuất chuỗi hiện tại.Zz001zz phải được mở cho đến khi trình xử lý lỗi bị tắt: xem issue with file descriptors.
Nếu c_stack là
Truethì dấu vết ngăn xếp C sẽ được in sau dấu vết Python, trừ khi hệ thống không hỗ trợ nó. Xemdump_c_stack()để biết thêm thông tin về khả năng tương thích.Thay đổi trong phiên bản 3.5: Đã thêm hỗ trợ để truyền bộ mô tả tệp cho chức năng này.
Thay đổi trong phiên bản 3.6: Trên Windows, trình xử lý ngoại lệ Windows cũng được cài đặt.
Thay đổi trong phiên bản 3.10: Hiện tại, kết xuất sẽ đề cập đến việc bộ sưu tập thu gom rác có đang chạy hay không nếu all_threads là đúng.
Thay đổi trong phiên bản 3.14: Chỉ luồng hiện tại bị hủy nếu GIL bị tắt để ngăn ngừa nguy cơ chạy đua dữ liệu.
Thay đổi trong phiên bản 3.14: Kết xuất hiện hiển thị dấu vết ngăn xếp C nếu c_stack là đúng.
- faulthandler.disable()¶
Tắt trình xử lý lỗi: gỡ cài đặt trình xử lý tín hiệu được cài đặt bởi
enable().
- faulthandler.is_enabled()¶
Kiểm tra xem trình xử lý lỗi có được bật hay không.
Loại bỏ dấu vết sau khi hết thời gian chờ¶
- faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)¶
Kết xuất dấu vết của tất cả các chuỗi, sau khoảng thời gian chờ là timeout giây hoặc cứ sau timeout giây nếu repeat là
True. Nếu exit làTrue, hãy gọi_exit()với trạng thái=1 sau khi loại bỏ dấu vết. (Lưu ý_exit()thoát khỏi quy trình ngay lập tức, điều đó có nghĩa là nó không thực hiện bất kỳ hoạt động dọn dẹp nào như xóa bộ đệm tệp.) Nếu hàm được gọi hai lần, lệnh gọi mới sẽ thay thế các tham số trước đó và đặt lại thời gian chờ. Bộ đếm thời gian có độ phân giải dưới giây.Zz002zz phải được mở cho đến khi truy nguyên được kết xuất hoặc
cancel_dump_traceback_later()được gọi: xem issue with file descriptors.Chức năng này được thực hiện bằng cách sử dụng một thread giám sát.
Thay đổi trong phiên bản 3.5: Đã thêm hỗ trợ để truyền bộ mô tả tệp cho chức năng này.
Thay đổi trong phiên bản 3.7: Chức năng này bây giờ luôn có sẵn.
- faulthandler.cancel_dump_traceback_later()¶
Hủy cuộc gọi cuối cùng tới
dump_traceback_later().
Bỏ dấu vết trên tín hiệu người dùng¶
- faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False)¶
Đăng ký tín hiệu người dùng: cài đặt trình xử lý cho tín hiệu signum để kết xuất dấu vết của tất cả các luồng hoặc của luồng hiện tại nếu all_threads là
False, vào file. Gọi trình xử lý trước đó nếu chuỗi làTrue.file phải được mở cho đến khi tín hiệu được
unregister()hủy đăng ký: xem issue with file descriptors.Không có sẵn trên Windows.
Thay đổi trong phiên bản 3.5: Đã thêm hỗ trợ để truyền bộ mô tả tệp cho chức năng này.
- faulthandler.unregister(signum)¶
Hủy đăng ký tín hiệu người dùng: gỡ cài đặt trình xử lý tín hiệu signum được cài đặt bởi
register(). Trả vềTruenếu tín hiệu đã được đăng ký,Falsenếu không.Không có sẵn trên Windows.
Vấn đề với bộ mô tả tập tin¶
enable(), dump_traceback_later() và register() giữ phần mô tả tệp của đối số file của chúng. Nếu tệp bị đóng và bộ mô tả tệp của nó được một tệp mới sử dụng lại hoặc nếu os.dup2() được sử dụng để thay thế bộ mô tả tệp, thì truy nguyên sẽ được ghi vào một tệp khác. Gọi lại các chức năng này mỗi khi tệp được thay thế.
Ví dụ¶
Ví dụ về lỗi phân đoạn trên Linux có và không bật trình xử lý lỗi:
$ python -c "nhập ctypes; ctypes.string_at(0)"
Lỗi phân đoạn
$ python -q -X trình xử lý lỗi
>>> nhập ctypes
>>> ctypes.string_at(0)
Lỗi Python nghiêm trọng: Lỗi phân đoạn
Chuỗi hiện tại 0x00007fb899f39700 (cuộc gọi gần đây nhất trước):
Tệp "/opt/python/Lib/ctypes/__init__.py", dòng 486 trong string_at
Tệp "<stdin>", dòng 1 trong <module>
Dấu vết ngăn xếp C của luồng hiện tại (cuộc gọi gần đây nhất được đặt trước):
Tệp nhị phân "/opt/python/python", tại _Py_DumpStack+0x42 [0x5b27f7d7147e]
Tệp nhị phân "/opt/python/python", tại +0x32dcbd [0x5b27f7d85cbd]
Tệp nhị phân "/opt/python/python", tại +0x32df8a [0x5b27f7d85f8a]
Tệp nhị phân "/usr/lib/libc.so.6", tại +0x3def0 [0x77b73226bef0]
Tệp nhị phân "/usr/lib/libc.so.6", tại +0x17ef9c [0x77b7323acf9c]
Tệp nhị phân "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", tại +0xcdf6 [0x77b7315dddf6]
Tệp nhị phân "/usr/lib/libffi.so.8", tại +0x7976 [0x77b73158f976]
Tệp nhị phân "/usr/lib/libffi.so.8", tại +0x413c [0x77b73158c13c]
Tệp nhị phân "/usr/lib/libffi.so.8", tại ffi_call+0x12e [0x77b73158ef0e]
Tệp nhị phân "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", tại +0x15a33 [0x77b7315e6a33]
Tệp nhị phân "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", tại +0x164fa [0x77b7315e74fa]
Tệp nhị phân "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", tại +0xc624 [0x77b7315dd624]
Tệp nhị phân "/opt/python/python", tại _PyObject_MakeTpCall+0xce [0x5b27f7b73883]
Tệp nhị phân "/opt/python/python", tại +0x11bab6 [0x5b27f7b73ab6]
Tệp nhị phân "/opt/python/python", tại PyObject_Vectorcall+0x23 [0x5b27f7b73b04]
Tệp nhị phân "/opt/python/python", tại _PyEval_EvalFrameDefault+0x490c [0x5b27f7cbb302]
Tệp nhị phân "/opt/python/python", tại +0x2818e6 [0x5b27f7cd98e6]
Tệp nhị phân "/opt/python/python", tại +0x281aab [0x5b27f7cd9aab]
Tệp nhị phân "/opt/python/python", tại PyEval_EvalCode+0xc5 [0x5b27f7cd9ba3]
Tệp nhị phân "/opt/python/python", tại +0x255957 [0x5b27f7cad957]
Tệp nhị phân "/opt/python/python", tại +0x255ab4 [0x5b27f7cadab4]
Tệp nhị phân "/opt/python/python", tại _PyEval_EvalFrameDefault+0x6c3e [0x5b27f7cbd634]
Tệp nhị phân "/opt/python/python", tại +0x2818e6 [0x5b27f7cd98e6]
Tệp nhị phân "/opt/python/python", tại +0x281aab [0x5b27f7cd9aab]
Tệp nhị phân "/opt/python/python", tại +0x11b6e1 [0x5b27f7b736e1]
Tệp nhị phân "/opt/python/python", tại +0x11d348 [0x5b27f7b75348]
Tệp nhị phân "/opt/python/python", tại +0x11d626 [0x5b27f7b75626]
Tệp nhị phân "/opt/python/python", tại PyObject_Call+0x20 [0x5b27f7b7565e]
Tệp nhị phân "/opt/python/python", tại +0x32a67a [0x5b27f7d8267a]
Tệp nhị phân "/opt/python/python", tại +0x32a7f8 [0x5b27f7d827f8]
Tệp nhị phân "/opt/python/python", tại +0x32ac1b [0x5b27f7d82c1b]
Tệp nhị phân "/opt/python/python", tại Py_RunMain+0x31 [0x5b27f7d82ebe]
<các cuộc gọi còn lại bị cắt ngắn>
Lỗi phân đoạn