faulthandler --- برون‌ریزی ردگیری پشته پایتون

اضافه شده در نسخه‌ی 3.3.


این ماژول شامل توابعی برای برون‌ریزی از ردگیری‌های پشته‌ی پایتون به‌صورت صریح، در صورت بروز خطا، پس از پایان مهلت، یا هنگام دریافت سیگنال کاربر است. faulthandler.enable() را فراخوانی کنید تا هندلرهای خطا برای سیگنال‌های SIGSEGV، SIGFPE، SIGABRT، SIGBUS و SIGILL نصب شوند. همچنین می‌توانید آن‌ها را در زمان راه‌اندازی با تنظیم متغیر محیطی PYTHONFAULTHANDLER یا با استفاده از گزینه‌ی خط فرمان -X faulthandler فعال کنید.

هندلر خطا با هندلرهای خطای سیستمی مانند Apport یا هندلر خطای ویندوز سازگار است. در صورتی که تابع sigaltstack() در دسترس باشد، این ماژول برای هندلرهای سیگنال از یک پشته جایگزین استفاده می‌کند. این امر به آن امکان می‌دهد که ردگیری پشته را حتی در صورت سرریز پشته نیز برون‌ریزی کند.

هندلر خطا (fault handler) در موارد فاجعه‌بار فراخوانی می‌شود و بنابراین تنها می‌تواند از توابع ایمن در برابر سیگنال (signal-safe) استفاده کند (برای مثال، نمی‌تواند حافظه‌ای را در هیپ تخصیص دهد). به دلیل این محدودیت، برون‌ریزی ردگیری پشته در مقایسه با ردگیری‌های پشته‌ی معمول پایتون حداقلی است:

  • فقط ASCII پشتیبانی می‌شود. هنگام کدگذاری از هندلر خطای backslashreplace استفاده می‌شود.

  • هر رشته به ۵۰۰ نویسه محدود است.

  • فقط نام پرونده، نام تابع و شماره‌ی خط نمایش داده می‌شوند. (بدون کد منبع)

  • It is limited to 100 frames per thread, and 100 threads (configurable via max_threads).

  • ترتیب معکوس است: جدیدترین فراخوانی ابتدا نمایش داده می‌شود.

به‌طور پیش‌فرض، ردگیری پشته پایتون در sys.stderr نوشته می‌شود. برای مشاهده ردگیری‌های پشته، برنامه‌ها باید در پایانه اجرا شوند. به‌عنوان جایگزین، می‌توان یک پرونده گزارش را به faulthandler.enable() پاس داد.

این ماژول به زبان C پیاده‌سازی شده است، بنابراین در صورت بروز فروپاشی یا هنگامی که پایتون در بن‌بست (deadlock) باشد، می‌توان ردگیری‌های پشته را برون‌ریزی کرد.

حالت توسعه پایتون در زمان راه‌اندازی پایتون، faulthandler.enable() را فراخوانی می‌کند.

همچنین ملاحظه نمائید

ماژول pdb

اشکال‌زدای تعاملی کد منبع برای برنامه‌های پایتون.

ماژول traceback

رابط استاندارد برای استخراج، قالب‌بندی و چاپ ردگیری‌های پشته در برنامه‌های پایتون.

برون‌ریزی ردگیری پشته

faulthandler.dump_traceback(file=sys.stderr, all_threads=True, *, max_threads=100)

Dump the tracebacks of all threads into file. If all_threads is False, dump only the current thread. max_threads caps the number of threads dumped.

همچنین ملاحظه نمائید

traceback.print_tb()، که می‌تواند برای چاپ یک شیء ردگیری پشته استفاده شود.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از ارسال توصیف‌گر پرونده به این تابع افزوده شد.

تغییر یافته در نسخه‌ی 3.15: Added the max_threads keyword argument.

برون‌ریزی پشته‌ی C

اضافه شده در نسخه‌ی 3.14.

faulthandler.dump_c_stack(file=sys.stderr)

برون‌ریزی ردگیری پشته‌ی C نخ جاری را در file بگیرید.

اگر ساخت پایتون از آن پشتیبانی نکند یا سیستم‌عامل ردگیری پشته را فراهم نکند، این مورد به‌جای پشته‌ی برون‌ریزی‌شده‌ی C، خطایی را چاپ می‌کند.

سازگاری پشته‌ی C

اگر سیستم از backtrace(3) یا dladdr1(3) در سطح C پشتیبانی نکند، برون‌ریزی پشته‌ی C کار نخواهد کرد. به‌جای پشته، خطایی چاپ خواهد شد.

علاوه بر این، برخی کامپایلرها از پیاده‌سازی CPython برای برون‌ریزی پشته‌های C (stack dumps) پشتیبانی نمی‌کنند. در نتیجه، حتی اگر سیستم‌عامل از تخلیه پشته‌ها پشتیبانی کند، ممکن است به‌جای پشته، خطای متفاوتی چاپ شود.

توجه

برون‌ریزی پشته‌های C می‌تواند بسته به سطح DWARF پرونده‌های دودویی موجود در پشته‌ی فراخوانی، به‌هر اندازه‌ای کند باشد.

وضعیت هندلر خطا

faulthandler.enable(file=sys.stderr, all_threads=True, c_stack=True, *, max_threads=100)

فعال‌سازی هندلر خطا : نصب هندلرهایی برای سیگنال‌های SIGSEGV، SIGFPE، SIGABRT، SIGBUS و SIGILL برای خروجی گرفتن از ردگیری پشته پایتون. اگر all_threads برابر True باشد، برای هر نخ در حال اجرا ردگیری پشته تولید می‌شود. در غیر این صورت، فقط ردگیری پشته نخ جاری خروجی گرفته می‌شود.

file باید تا پیش از غیرفعال‌شدن هندلر خطا باز بماند: مشکل توصیف‌گرهای پرونده را ببینید.

اگر c_stack برابر True باشد، ردگیری پشته C پس از ردگیری پشته پایتون چاپ می‌شود، مگر آنکه سیستم از آن پشتیبانی نکند. برای اطلاعات بیشتر درباره سازگاری، dump_c_stack() را ببینید.

max_threads caps the number of threads dumped when a fatal signal fires.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از ارسال توصیف‌گر پرونده به این تابع افزوده شد.

تغییر یافته در نسخه‌ی 3.6: در ویندوز، یک هندلر برای استثنای ویندوز نیز نصب می‌شود.

تغییر یافته در نسخه‌ی 3.10: اگر all_threads true باشد، اکنون در برون‌ریزی ذکر می‌شود که آیا یک جمع‌آوری زباله‌روبی در حال اجرا است یا خیر.

تغییر یافته در نسخه‌ی 3.14: در صورت غیرفعال بودن GIL، فقط نخ جاری dump می‌شود تا از خطر رقابت‌های داده‌ای جلوگیری شود.

تغییر یافته در نسخه‌ی 3.14: برون‌ریزی اکنون در صورتی که c_stack برابر true باشد، ردگیری پشته‌ی C را نمایش می‌دهد.

تغییر یافته در نسخه‌ی 3.15: Added the max_threads keyword argument.

faulthandler.disable()

غیرفعال‌سازی هندلر خطا : حذف مدیرهای سیگنال نصب‌شده توسط enable().

faulthandler.is_enabled()

بررسی کنید که آیا هندلر خطا فعال است یا خیر.

برون‌ریزی ردگیری‌های پشته پس از پایان مهلت

faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False, *, max_threads=100)

Dump the tracebacks of all threads, after a timeout of timeout seconds, or every timeout seconds if repeat is True. If exit is True, call _exit() with status=1 after dumping the tracebacks. (Note _exit() exits the process immediately, which means it doesn't do any cleanup like flushing file buffers.) If the function is called twice, the new call replaces previous parameters and resets the timeout. The timer has a sub-second resolution. max_threads caps the number of threads dumped.

file باید تا زمانی که ردگیری پشته برون‌ریزی شود یا cancel_dump_traceback_later() فراخوانی شود، باز بماند: مسئله‌ی توصیف‌گرهای پرونده را ببینید.

این تابع با استفاده از یک نخ دیده‌بان (watchdog thread) پیاده‌سازی شده است.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از ارسال توصیف‌گر پرونده به این تابع افزوده شد.

تغییر یافته در نسخه‌ی 3.7: این تابع اکنون همیشه در دسترس است.

تغییر یافته در نسخه‌ی 3.15: Added the max_threads keyword argument.

faulthandler.cancel_dump_traceback_later()

آخرین فراخوانی dump_traceback_later() را لغو می‌کند.

برون‌ریزی ردگیری پشته در سیگنال کاربر

faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False, *, max_threads=100)

Register a user signal: install a handler for the signum signal to dump the traceback of all threads, or of the current thread if all_threads is False, into file. Call the previous handler if chain is True. max_threads caps the number of threads dumped.

file باید تا زمانی که سیگنال توسط unregister() از ثبت خارج شود، باز بماند: به مشکل توصیف‌گرهای پرونده مراجعه کنید.

در ویندوز در دسترس نیست.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از ارسال توصیف‌گر پرونده به این تابع افزوده شد.

تغییر یافته در نسخه‌ی 3.15: Added the max_threads keyword argument.

faulthandler.unregister(signum)

لغو ثبت یک سیگنال کاربر: حذف هندلر سیگنال signum نصب‌شده توسط register(). اگر سیگنال ثبت‌شده باشد، True و در غیر این صورت False برمی‌گرداند.

در ویندوز در دسترس نیست.

مشکل مربوط به توصیف‌گرهای پرونده

enable()، dump_traceback_later() و register() توصیف‌گر فایلِ آرگومان file خود را نگه می‌دارند. اگر پرونده بسته شود و توصیف‌گر پرونده آن توسط یک پرونده جدید دوباره استفاده شود، یا اگر از os.dup2() برای جایگزینی توصیف‌گر پرونده استفاده شود، ردگیری پشته در یک پرونده دیگر نوشته خواهد شد. هر بار که پرونده جایگزین می‌شود، این توابع را دوباره فراخوانی کنید.

مثال

نمونه‌ای از خطای قطعه‌بندی (segmentation fault) در لینوکس، با فعال‌سازی مدیر خطا و بدون فعال‌سازی آن:

$ python -c "import ctypes; ctypes.string_at(0)"
Segmentation fault

$ python -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault

Current thread 0x00007fb899f39700 (most recent call first):
  File "/opt/python/Lib/ctypes/__init__.py", line 486 in string_at
  File "<stdin>", line 1 in <module>

Current thread's C stack trace (most recent call first):
  Binary file "/opt/python/python", at _Py_DumpStack+0x42 [0x5b27f7d7147e]
  Binary file "/opt/python/python", at +0x32dcbd [0x5b27f7d85cbd]
  Binary file "/opt/python/python", at +0x32df8a [0x5b27f7d85f8a]
  Binary file "/usr/lib/libc.so.6", at +0x3def0 [0x77b73226bef0]
  Binary file "/usr/lib/libc.so.6", at +0x17ef9c [0x77b7323acf9c]
  Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0xcdf6 [0x77b7315dddf6]
  Binary file "/usr/lib/libffi.so.8", at +0x7976 [0x77b73158f976]
  Binary file "/usr/lib/libffi.so.8", at +0x413c [0x77b73158c13c]
  Binary file "/usr/lib/libffi.so.8", at ffi_call+0x12e [0x77b73158ef0e]
  Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0x15a33 [0x77b7315e6a33]
  Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0x164fa [0x77b7315e74fa]
  Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0xc624 [0x77b7315dd624]
  Binary file "/opt/python/python", at _PyObject_MakeTpCall+0xce [0x5b27f7b73883]
  Binary file "/opt/python/python", at +0x11bab6 [0x5b27f7b73ab6]
  Binary file "/opt/python/python", at PyObject_Vectorcall+0x23 [0x5b27f7b73b04]
  Binary file "/opt/python/python", at _PyEval_EvalFrameDefault+0x490c [0x5b27f7cbb302]
  Binary file "/opt/python/python", at +0x2818e6 [0x5b27f7cd98e6]
  Binary file "/opt/python/python", at +0x281aab [0x5b27f7cd9aab]
  Binary file "/opt/python/python", at PyEval_EvalCode+0xc5 [0x5b27f7cd9ba3]
  Binary file "/opt/python/python", at +0x255957 [0x5b27f7cad957]
  Binary file "/opt/python/python", at +0x255ab4 [0x5b27f7cadab4]
  Binary file "/opt/python/python", at _PyEval_EvalFrameDefault+0x6c3e [0x5b27f7cbd634]
  Binary file "/opt/python/python", at +0x2818e6 [0x5b27f7cd98e6]
  Binary file "/opt/python/python", at +0x281aab [0x5b27f7cd9aab]
  Binary file "/opt/python/python", at +0x11b6e1 [0x5b27f7b736e1]
  Binary file "/opt/python/python", at +0x11d348 [0x5b27f7b75348]
  Binary file "/opt/python/python", at +0x11d626 [0x5b27f7b75626]
  Binary file "/opt/python/python", at PyObject_Call+0x20 [0x5b27f7b7565e]
  Binary file "/opt/python/python", at +0x32a67a [0x5b27f7d8267a]
  Binary file "/opt/python/python", at +0x32a7f8 [0x5b27f7d827f8]
  Binary file "/opt/python/python", at +0x32ac1b [0x5b27f7d82c1b]
  Binary file "/opt/python/python", at Py_RunMain+0x31 [0x5b27f7d82ebe]
  <truncated rest of calls>
Segmentation fault