Exemple #1
0
static jboolean installSignals(Env* env) {
#if defined(DARWIN)
    // On Darwin SIGBUS is generated when dereferencing NULL pointers
    if (installSignalHandlerIfNeeded(SIGBUS, create_sigaction(&signalHandler_npe_so_nochaining), NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }
#endif

    if (installSignalHandlerIfNeeded(SIGSEGV, create_sigaction(&signalHandler_npe_so_nochaining), NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }

    if (installSignalHandlerIfNeeded(DUMP_THREAD_STACK_TRACE_SIGNAL, create_sigaction(&signalHandler_dump_thread), NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }

    int err;
    if ((err = pthread_sigmask(0, NULL, &env->currentThread->signalMask)) != 0) {
        rvmThrowInternalErrorErrno(env, err);
        rvmTearDownSignals(env);
        return FALSE;        
    }

    return TRUE;
}
Exemple #2
0
static jboolean reinstallSavedSignals(Env* env, SavedSignals* savedSignals) {
    if (installSignalHandlerIfNeeded(DUMP_THREAD_STACK_TRACE_SIGNAL, create_sigaction(&signalHandler_dump_thread), NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }

    if (installSignalHandlerIfNeeded(BLOCKED_THREAD_SIGNAL, savedSignals->blockedThreadSignal, NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }

    return TRUE;
}
Exemple #3
0
/**
 * Associates the specified Env* with the current thread.
 */
static void setThreadEnv(Env* env) {
    int err = pthread_setspecific(tlsEnvKey, env);
    assert(err == 0);
    if (err != 0) {
        rvmThrowInternalErrorErrno(env, err);
    }
}
Exemple #4
0
static jboolean installChainingSignals(Env* env) {
#if defined(DARWIN)
    // On Darwin SIGBUS is generated when dereferencing NULL pointers
    if (installSignalHandlerIfNeeded(SIGBUS, create_sigaction(&signalHandler_npe_so_chaining), &sigbusFallback) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }
#endif

    if (installSignalHandlerIfNeeded(SIGSEGV, create_sigaction(&signalHandler_npe_so_chaining), &sigsegvFallback) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        return FALSE;
    }

    return TRUE;
}
Exemple #5
0
jboolean rvmInstallThreadSignalMask(Env* env) {
    int err;
    if ((err = pthread_sigmask(0, NULL, &env->currentThread->signalMask)) != 0) {
        rvmThrowInternalErrorErrno(env, err);
        return FALSE;        
    }
    return TRUE;
}
Exemple #6
0
jlong rvmStartThread(Env* env, JavaThread* threadObj) {
    Env* newEnv = rvmCreateEnv(env->vm);
    if (!newEnv) {
        rvmThrowOutOfMemoryError(env); // rvmCreateEnv() doesn't throw OutOfMemoryError if allocation fails
        return 0;
    }

    rvmLockThreadsList();
    if (threadObj->threadPtr != 0) {
        rvmThrowIllegalStateException(env, "thread has already been started");
        rvmUnlockThreadsList();
        return 0;
    }
    Thread* thread = allocThread(env);
    if (!thread) {
        rvmUnlockThreadsList();
        return 0;
    }

    size_t stackSize = (size_t) threadObj->stackSize;
    if (stackSize == 0) {
        stackSize = THREAD_DEFAULT_STACK_SIZE;
    } else if (stackSize < THREAD_MIN_STACK_SIZE) {
        stackSize = THREAD_MIN_STACK_SIZE;
    }
    stackSize += THREAD_SIGNAL_STACK_SIZE;
    stackSize = (stackSize + THREAD_STACK_SIZE_MULTIPLE - 1) & ~(THREAD_STACK_SIZE_MULTIPLE - 1);

    pthread_attr_t threadAttr;
    pthread_attr_init(&threadAttr);
    pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
    pthread_attr_setstacksize(&threadAttr, stackSize);
    pthread_attr_setguardsize(&threadAttr, THREAD_STACK_GUARD_SIZE);

    ThreadEntryPointArgs args = {0};
    args.env = newEnv;
    args.thread = thread;
    args.threadObj = threadObj;
    int err = 0;
    if ((err = pthread_create(&thread->pThread, &threadAttr, startThreadEntryPoint, &args)) != 0) {
        rvmUnlockThreadsList();
        rvmThrowInternalErrorErrno(env, err);
        return 0;
    }

    while (thread->status != THREAD_STARTING) {
        pthread_cond_wait(&threadStartCond, &threadsLock);
    }

    DL_PREPEND(threads, thread);
    pthread_cond_broadcast(&threadsChangedCond);
    
    thread->status = THREAD_VMWAIT;
    pthread_cond_broadcast(&threadStartCond);
    rvmUnlockThreadsList();

    return PTR_TO_LONG(thread);
}
Exemple #7
0
static jboolean installSignalHandlers(Env* env) {
    struct sigaction sa;

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
    sa.sa_sigaction = &signalHandler_npe_so;

#if defined(DARWIN)
    // On Darwin SIGBUS is generated when dereferencing NULL pointers
    if (sigaction(SIGBUS, &sa, NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        rvmTearDownSignals(env);
        return FALSE;
    }
#endif

    if (sigaction(SIGSEGV, &sa, NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        rvmTearDownSignals(env);
        return FALSE;
    }

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
    sa.sa_sigaction = &signalHandler_dump_thread;

    if (sigaction(DUMP_THREAD_STACK_TRACE_SIGNAL, &sa, NULL) != 0) {
        rvmThrowInternalErrorErrno(env, errno);
        rvmTearDownSignals(env);
        return FALSE;
    }

    int err;
    if ((err = pthread_sigmask(0, NULL, &env->currentThread->signalMask)) != 0) {
        rvmThrowInternalErrorErrno(env, err);
        rvmTearDownSignals(env);
        return FALSE;        
    }

    return TRUE;
}
Exemple #8
0
static jboolean initThread(Env* env, Thread* thread, JavaThread* threadObj) {
    // NOTE: threadsLock must be held
    int err = 0;
    pthread_cond_init(&thread->waitCond, NULL);
    if ((err = rvmInitMutex(&thread->waitMutex)) != 0) {
        rvmThrowInternalErrorErrno(env, err);
        return FALSE;
    }
    thread->threadId = nextThreadId++;
    thread->threadObj = threadObj;
    threadObj->threadPtr = PTR_TO_LONG(thread);
    env->currentThread = thread;
    env->attachCount = 1;
    return TRUE;
}