summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-01-18 19:47:13 (GMT)
committerGitHub <noreply@github.com>2021-01-18 19:47:13 (GMT)
commit250035d134ad482e724f73ce654682254b513ee0 (patch)
tree48d2b3627adfe0b0e04aaaee25f35f4999cde254 /Python
parentf7b5bacd7a0b2084ce699eda6f6f4b1adfa16590 (diff)
downloadcpython-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.c41
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