Exemple #1
0
// request:
// 0: nothing
// 1: get state
// 2: throw sigint if `!defer_signal && io_wait` or if force throw threshold
//    is reached
// 3: exit with `thread0_exit_state`
void usr2_handler(int sig, siginfo_t *info, void *ctx)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    sig_atomic_t request = jl_atomic_exchange(&ptls->signal_request, 0);
    if (request == 1) {
        signal_context = jl_to_bt_context(ctx);

        pthread_mutex_lock(&in_signal_lock);
        pthread_cond_broadcast(&signal_caught_cond);
        pthread_cond_wait(&exit_signal_cond, &in_signal_lock);
        request = jl_atomic_exchange(&ptls->signal_request, 0);
        assert(request == 1);
        (void)request;
        pthread_cond_broadcast(&signal_caught_cond);
        pthread_mutex_unlock(&in_signal_lock);
    }
    else if (request == 2) {
        jl_unblock_signal(sig);
        int force = jl_check_force_sigint();
        if (force || (!ptls->defer_signal && ptls->io_wait)) {
            jl_safepoint_consume_sigint();
            if (force)
                jl_safe_printf("WARNING: Force throwing a SIGINT\n");
            // Force a throw
            jl_clear_force_sigint();
            jl_throw_in_ctx(ptls, jl_interrupt_exception, ctx);
        }
    }
    else if (request == 3) {
        jl_unblock_signal(sig);
        jl_call_in_ctx(ptls, jl_exit_thread0_cb, ctx);
    }
}
Exemple #2
0
static void segv_handler(int sig, siginfo_t *info, void *context)
{
    assert(sig == SIGSEGV || sig == SIGBUS);

#ifdef JULIA_ENABLE_THREADING
    if (info->si_addr == jl_gc_signal_page) {
        jl_unblock_signal(sig);
        jl_gc_signal_wait();
        return;
    }
#endif
    if (jl_safe_restore || is_addr_on_stack(jl_get_ptls_states(), info->si_addr)) { // stack overflow, or restarting jl_
        jl_unblock_signal(sig);
        jl_throw(jl_stackovf_exception);
    }
    else if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {  // writing to read-only memory (e.g., mmap)
        jl_unblock_signal(sig);
        jl_throw(jl_readonlymemory_exception);
    }
    else {
#ifdef SEGV_EXCEPTION
        jl_unblock_signal(sig);
        jl_throw(jl_segv_exception);
#else
        sigdie_handler(sig, info, context);
#endif
    }
}
Exemple #3
0
static void segv_handler(int sig, siginfo_t *info, void *context)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    assert(sig == SIGSEGV || sig == SIGBUS);

    if (jl_addr_is_safepoint((uintptr_t)info->si_addr)) {
        jl_unblock_signal(sig);
#ifdef JULIA_ENABLE_THREADING
        jl_set_gc_and_wait();
        // Do not raise sigint on worker thread
        if (ptls->tid != 0)
            return;
#endif
        if (ptls->defer_signal) {
            jl_safepoint_defer_sigint();
        }
        else if (jl_safepoint_consume_sigint()) {
            jl_clear_force_sigint();
            jl_throw_in_ctx(ptls, jl_interrupt_exception, context);
        }
        return;
    }
    if (ptls->safe_restore || is_addr_on_stack(ptls, info->si_addr)) { // stack overflow, or restarting jl_
        jl_unblock_signal(sig);
        jl_throw_in_ctx(ptls, jl_stackovf_exception, context);
    }
    else if (jl_is_on_sigstack(ptls, info->si_addr, context)) {
        // This mainly happens when one of the finalizers during final cleanup
        // on the signal stack has a deep/infinite recursion.
        // There isn't anything more we can do
        // (we are already corrupting that stack running this function)
        // so just call `_exit` to terminate immediately.
        jl_safe_printf("ERROR: Signal stack overflow, exit\n");
        _exit(sig + 128);
    }
    else if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {  // writing to read-only memory (e.g., mmap)
        jl_unblock_signal(sig);
        jl_throw_in_ctx(ptls, jl_readonlymemory_exception, context);
    }
    else {
#ifdef SEGV_EXCEPTION
        jl_unblock_signal(sig);
        jl_throw_in_ctx(ptls, jl_segv_exception, context);
#else
        sigdie_handler(sig, info, context);
#endif
    }
}
Exemple #4
0
void fpe_handler(int sig, siginfo_t *info, void *context)
{
    (void)info;
    jl_ptls_t ptls = jl_get_ptls_states();
    jl_unblock_signal(sig);
    jl_throw_in_ctx(ptls, jl_diverror_exception, context);
}
Exemple #5
0
void usr2_handler(int sig, siginfo_t *info, void *ctx)
{
    ucontext_t *context = (ucontext_t*)ctx;
    if ((remote_sig > 0 && waiting_for < 0) || waiting_for == ti_tid) {
        int realsig = remote_sig;
#ifdef __APPLE__
        signal_context = (unw_context_t*)&context->uc_mcontext->__ss;
#else
        signal_context = (unw_context_t*)context;
#endif

        pthread_mutex_lock(&in_signal_lock);
        wait_barrier();
        pthread_cond_wait(&exit_signal_cond, &in_signal_lock);
        wait_barrier();
        pthread_mutex_unlock(&in_signal_lock);

        if (ti_tid == 0 && realsig == SIGINT) {
            if (jl_defer_signal) {
                jl_signal_pending = realsig;
            }
            else {
                jl_signal_pending = 0;
                jl_unblock_signal(sig);
                jl_throw(jl_interrupt_exception);
            }
        }
    }
}
Exemple #6
0
static void segv_handler(int sig, siginfo_t *info, void *context)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    assert(sig == SIGSEGV || sig == SIGBUS);

    if (jl_addr_is_safepoint((uintptr_t)info->si_addr)) {
        jl_unblock_signal(sig);
#ifdef JULIA_ENABLE_THREADING
        jl_set_gc_and_wait();
        // Do not raise sigint on worker thread
        if (ptls->tid != 0)
            return;
#endif
        if (jl_get_ptls_states()->defer_signal) {
            jl_safepoint_defer_sigint();
        }
        else if (jl_safepoint_consume_sigint()) {
            jl_clear_force_sigint();
            jl_throw_in_ctx(jl_interrupt_exception, context);
        }
        return;
    }
    if (ptls->safe_restore || is_addr_on_stack(jl_get_ptls_states(), info->si_addr)) { // stack overflow, or restarting jl_
        jl_unblock_signal(sig);
        jl_throw_in_ctx(jl_stackovf_exception, context);
    }
    else if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {  // writing to read-only memory (e.g., mmap)
        jl_unblock_signal(sig);
        jl_throw_in_ctx(jl_readonlymemory_exception, context);
    }
    else {
#ifdef SEGV_EXCEPTION
        jl_unblock_signal(sig);
        jl_throw_in_ctx(jl_segv_exception, context);
#else
        sigdie_handler(sig, info, context);
#endif
    }
}
Exemple #7
0
void fpe_handler(int sig, siginfo_t *info, void *context)
{
    (void)info;
    jl_unblock_signal(sig);
    jl_throw_in_ctx(jl_diverror_exception, context);
}
Exemple #8
0
void fpe_handler(int arg)
{
    (void)arg;
    jl_unblock_signal(SIGFPE);
    jl_throw(jl_diverror_exception);
}