static void faulthandler_user(int signum) { user_signal_t *user; int save_errno = errno; user = &user_signals[signum]; if (!user->enabled) return; faulthandler_dump_traceback(user->fd, user->all_threads, user->interp); #ifdef HAVE_SIGACTION if (user->chain) { (void)sigaction(signum, &user->previous, NULL); errno = save_errno; /* call the previous signal handler */ raise(signum); save_errno = errno; (void)faulthandler_register(signum, user->chain, NULL); errno = save_errno; } #else if (user->chain) { errno = save_errno; /* call the previous signal handler */ user->previous(signum); } #endif }
static PyObject* faulthandler_register_py(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL}; int signum; PyObject *file = NULL; int all_threads = 1; int chain = 0; int fd; user_signal_t *user; _Py_sighandler_t previous; PyThreadState *tstate; int err; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|Oii:register", kwlist, &signum, &file, &all_threads, &chain)) return NULL; if (!check_signum(signum)) return NULL; tstate = get_thread_state(); if (tstate == NULL) return NULL; file = faulthandler_get_fileno(file, &fd); if (file == NULL) return NULL; if (user_signals == NULL) { user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t)); if (user_signals == NULL) return PyErr_NoMemory(); memset(user_signals, 0, NSIG * sizeof(user_signal_t)); } user = &user_signals[signum]; if (!user->enabled) { err = faulthandler_register(signum, chain, &previous); if (err) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } user->previous = previous; } Py_XDECREF(user->file); Py_INCREF(file); user->file = file; user->fd = fd; user->all_threads = all_threads; user->chain = chain; user->interp = tstate->interp; user->enabled = 1; Py_RETURN_NONE; }
static void faulthandler_user(int signum) { user_signal_t *user; PyThreadState *tstate; int save_errno = errno; user = &user_signals[signum]; if (!user->enabled) return; #ifdef WITH_THREAD /* PyThreadState_Get() doesn't give the state of the current thread if the thread doesn't hold the GIL. Read the thread local storage (TLS) instead: call PyGILState_GetThisThreadState(). */ tstate = PyGILState_GetThisThreadState(); #else tstate = PyThreadState_Get(); #endif if (user->all_threads) _Py_DumpTracebackThreads(user->fd, user->interp, tstate); else { if (tstate != NULL) _Py_DumpTraceback(user->fd, tstate); } #ifdef HAVE_SIGACTION if (user->chain) { (void)sigaction(signum, &user->previous, NULL); errno = save_errno; /* call the previous signal handler */ raise(signum); save_errno = errno; (void)faulthandler_register(signum, user->chain, NULL); errno = save_errno; } #else if (user->chain) { errno = save_errno; /* call the previous signal handler */ user->previous(signum); } #endif }