diff options
author | Victor Stinner <vstinner@python.org> | 2021-01-18 19:47:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-18 19:47:13 (GMT) |
commit | 250035d134ad482e724f73ce654682254b513ee0 (patch) | |
tree | 48d2b3627adfe0b0e04aaaee25f35f4999cde254 /Python | |
parent | f7b5bacd7a0b2084ce699eda6f6f4b1adfa16590 (diff) | |
download | cpython-250035d134ad482e724f73ce654682254b513ee0.zip cpython-250035d134ad482e724f73ce654682254b513ee0.tar.gz cpython-250035d134ad482e724f73ce654682254b513ee0.tar.bz2 |
bpo-42923: Dump extension modules on fatal error (GH-24207)
The Py_FatalError() function and the faulthandler module now dump the
list of extension modules on a fatal error.
Add _Py_DumpExtensionModules() and _PyModule_IsExtension() internal
functions.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pylifecycle.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index c020717..ee64b0f 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2496,6 +2496,45 @@ fatal_error_exit(int status) } +// Dump the list of extension modules of sys.modules into fd file descriptor. +// This function is called by a signal handler in faulthandler: avoid memory +// allocations and keep the implementation simple. For example, the list +// is not sorted on purpose. +void +_Py_DumpExtensionModules(int fd, PyInterpreterState *interp) +{ + if (interp == NULL) { + return; + } + PyObject *modules = interp->modules; + if (!PyDict_Check(modules)) { + return; + } + + PUTS(fd, "\nExtension modules: "); + + Py_ssize_t pos = 0; + PyObject *key, *value; + int comma = 0; + while (PyDict_Next(modules, &pos, &key, &value)) { + if (!PyUnicode_Check(key)) { + continue; + } + if (!_PyModule_IsExtension(value)) { + continue; + } + + if (comma) { + PUTS(fd, ", "); + } + comma = 1; + + _Py_DumpASCII(fd, key); + } + PUTS(fd, "\n"); +} + + static void _Py_NO_RETURN fatal_error(int fd, int header, const char *prefix, const char *msg, int status) @@ -2557,6 +2596,8 @@ fatal_error(int fd, int header, const char *prefix, const char *msg, _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); } + _Py_DumpExtensionModules(fd, interp); + /* The main purpose of faulthandler is to display the traceback. This function already did its best to display a traceback. Disable faulthandler to prevent writing a second traceback |