summaryrefslogtreecommitdiff
path: root/Modules/faulthandler.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-11-15 15:48:08 -0800
committerGitHub <noreply@github.com>2017-11-15 15:48:08 -0800
commitf7e5b56c37eb859e225e886c79c5d742c567ee95 (patch)
tree7d722ca38595aaa68e02a1ee1ea53e17a54b0188 /Modules/faulthandler.c
parent43605e6bfa8d49612df4a38460d063d6ba781906 (diff)
downloadcpython-git-f7e5b56c37eb859e225e886c79c5d742c567ee95.tar.gz
bpo-32030: Split Py_Main() into subfunctions (#4399)
* Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
Diffstat (limited to 'Modules/faulthandler.c')
-rw-r--r--Modules/faulthandler.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index 33edc0547e..b6d5aee9b1 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -1281,47 +1281,54 @@ PyInit_faulthandler(void)
return m;
}
-/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
- is defined, or if sys._xoptions has a 'faulthandler' key. */
-
static int
-faulthandler_env_options(void)
+faulthandler_init_enable(void)
{
- PyObject *xoptions, *key, *module, *res;
- char *p;
+ PyObject *module = PyImport_ImportModule("faulthandler");
+ if (module == NULL) {
+ return -1;
+ }
- if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
- /* PYTHONFAULTHANDLER environment variable is missing
- or an empty string */
- int has_key;
+ PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
+ Py_DECREF(module);
+ if (res == NULL) {
+ return -1;
+ }
+ Py_DECREF(res);
- xoptions = PySys_GetXOptions();
- if (xoptions == NULL)
- return -1;
+ return 0;
+}
- key = PyUnicode_FromString("faulthandler");
- if (key == NULL)
- return -1;
+/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
+ is defined, or if sys._xoptions has a 'faulthandler' key. */
- has_key = PyDict_Contains(xoptions, key);
- Py_DECREF(key);
- if (has_key <= 0)
- return has_key;
+static int
+faulthandler_init_parse(void)
+{
+ char *p = Py_GETENV("PYTHONFAULTHANDLER");
+ if (p && *p != '\0') {
+ return 1;
}
- module = PyImport_ImportModule("faulthandler");
- if (module == NULL) {
+ /* PYTHONFAULTHANDLER environment variable is missing
+ or an empty string */
+ PyObject *xoptions = PySys_GetXOptions();
+ if (xoptions == NULL) {
return -1;
}
- res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
- Py_DECREF(module);
- if (res == NULL)
+
+ PyObject *key = PyUnicode_FromString("faulthandler");
+ if (key == NULL) {
return -1;
- Py_DECREF(res);
- return 0;
+ }
+
+ int has_key = PyDict_Contains(xoptions, key);
+ Py_DECREF(key);
+ return has_key;
}
-int _PyFaulthandler_Init(void)
+_PyInitError
+_PyFaulthandler_Init(void)
{
#ifdef HAVE_SIGALTSTACK
int err;
@@ -1345,14 +1352,22 @@ int _PyFaulthandler_Init(void)
thread.cancel_event = PyThread_allocate_lock();
thread.running = PyThread_allocate_lock();
if (!thread.cancel_event || !thread.running) {
- PyErr_SetString(PyExc_RuntimeError,
- "could not allocate locks for faulthandler");
- return -1;
+ return _Py_INIT_ERR("failed to allocate locks for faulthandler");
}
PyThread_acquire_lock(thread.cancel_event, 1);
#endif
- return faulthandler_env_options();
+ int enable = faulthandler_init_parse();
+ if (enable < 0) {
+ return _Py_INIT_ERR("failed to parse faulthandler env var and cmdline");
+ }
+
+ if (enable) {
+ if (faulthandler_init_enable() < 0) {
+ return _Py_INIT_ERR("failed to enable faulthandler");
+ }
+ }
+ return _Py_INIT_OK();
}
void _PyFaulthandler_Fini(void)