Exemple #1
0
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
}
Exemple #2
0
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;
}
Exemple #3
0
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
}