mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 08:35:37 -04:00
Feat[jre_launcher]: reset Android's debuggerd/ART signal handlers
This allows the JVM to use its own crash handler and dump the native crash stack into stderr, which makes it more convenient for the end-user to see the error. This does not disrupt ART as the signal handlers get handled through Android's integrated libsigchain first.
This commit is contained in:
parent
73fc447b80
commit
6998624e44
@ -51,25 +51,6 @@ static const char** const_appclasspath = NULL;
|
|||||||
static const jboolean const_javaw = JNI_FALSE;
|
static const jboolean const_javaw = JNI_FALSE;
|
||||||
static const jboolean const_cpwildcard = JNI_TRUE;
|
static const jboolean const_cpwildcard = JNI_TRUE;
|
||||||
static const jint const_ergo_class = 0; // DEFAULT_POLICY
|
static const jint const_ergo_class = 0; // DEFAULT_POLICY
|
||||||
static struct sigaction old_sa[NSIG];
|
|
||||||
|
|
||||||
void (*__old_sa)(int signal, siginfo_t *info, void *reserved);
|
|
||||||
int (*JVM_handle_linux_signal)(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized);
|
|
||||||
|
|
||||||
void android_sigaction(int signal, siginfo_t *info, void *reserved) {
|
|
||||||
printf("process killed with signal %d code %p addr %p\n", signal,info->si_code,info->si_addr);
|
|
||||||
if (JVM_handle_linux_signal == NULL) { // should not happen, but still
|
|
||||||
__old_sa = old_sa[signal].sa_sigaction;
|
|
||||||
__old_sa(signal,info,reserved);
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
// Based on https://github.com/PojavLauncherTeam/openjdk-multiarch-jdk8u/blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/linux/vm/os_linux.cpp#L4688-4693
|
|
||||||
int orig_errno = errno; // Preserve errno value over signal handler.
|
|
||||||
JVM_handle_linux_signal(signal, info, reserved, true);
|
|
||||||
errno = orig_errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typedef jint JNI_CreateJavaVM_func(JavaVM **pvm, void **penv, void *args);
|
|
||||||
|
|
||||||
typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */
|
typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */
|
||||||
int jargc, const char** jargv, /* java args */
|
int jargc, const char** jargv, /* java args */
|
||||||
@ -87,6 +68,19 @@ typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */
|
|||||||
static jint launchJVM(int margc, char** margv) {
|
static jint launchJVM(int margc, char** margv) {
|
||||||
void* libjli = dlopen("libjli.so", RTLD_LAZY | RTLD_GLOBAL);
|
void* libjli = dlopen("libjli.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
|
||||||
|
// Unset all signal handlers to create a good slate for JVM signal detection.
|
||||||
|
struct sigaction clean_sa;
|
||||||
|
memset(&clean_sa, 0, sizeof (struct sigaction));
|
||||||
|
for(int sigid = SIGHUP; sigid < NSIG; sigid++) {
|
||||||
|
// For some reason Android specifically checks if you set SIGSEGV to SIG_DFL.
|
||||||
|
// There's probably a good reason for that but the signal handler here is
|
||||||
|
// temporary and will be replaced by the Java VM's signal/crash handler.
|
||||||
|
// Work around the warning by using SIG_IGN for SIGSEGV
|
||||||
|
if(sigid == SIGSEGV) clean_sa.sa_handler = SIG_IGN;
|
||||||
|
else clean_sa.sa_handler = SIG_DFL;
|
||||||
|
sigaction(sigid, &clean_sa, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Boardwalk: silence
|
// Boardwalk: silence
|
||||||
// LOGD("JLI lib = %x", (int)libjli);
|
// LOGD("JLI lib = %x", (int)libjli);
|
||||||
if (NULL == libjli) {
|
if (NULL == libjli) {
|
||||||
@ -130,35 +124,8 @@ static jint launchJVM(int margc, char** margv) {
|
|||||||
* Signature: ([Ljava/lang/String;)I
|
* Signature: ([Ljava/lang/String;)I
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env, jclass clazz, jobjectArray argsArray) {
|
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env, jclass clazz, jobjectArray argsArray) {
|
||||||
#ifdef TRY_SIG2JVM
|
|
||||||
void* libjvm = dlopen("libjvm.so", RTLD_LAZY | RTLD_GLOBAL);
|
|
||||||
if (NULL == libjvm) {
|
|
||||||
LOGE("JVM lib = NULL: %s", dlerror());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
JVM_handle_linux_signal = dlsym(libjvm, "JVM_handle_linux_signal");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jint res = 0;
|
jint res = 0;
|
||||||
// int i;
|
|
||||||
//Prepare the signal trapper
|
|
||||||
struct sigaction catcher;
|
|
||||||
memset(&catcher,0,sizeof(sigaction));
|
|
||||||
catcher.sa_sigaction = android_sigaction;
|
|
||||||
catcher.sa_flags = SA_SIGINFO|SA_RESTART;
|
|
||||||
// SA_RESETHAND;
|
|
||||||
#define CATCHSIG(X) sigaction(X, &catcher, &old_sa[X])
|
|
||||||
CATCHSIG(SIGILL);
|
|
||||||
//CATCHSIG(SIGABRT);
|
|
||||||
CATCHSIG(SIGBUS);
|
|
||||||
CATCHSIG(SIGFPE);
|
|
||||||
#ifdef TRY_SIG2JVM
|
|
||||||
CATCHSIG(SIGSEGV);
|
|
||||||
#endif
|
|
||||||
CATCHSIG(SIGSTKFLT);
|
|
||||||
CATCHSIG(SIGPIPE);
|
|
||||||
CATCHSIG(SIGXFSZ);
|
|
||||||
//Signal trapper ready
|
|
||||||
|
|
||||||
// Save dalvik JNIEnv pointer for JVM launch thread
|
// Save dalvik JNIEnv pointer for JVM launch thread
|
||||||
pojav_environ->dalvikJNIEnvPtr_ANDROID = env;
|
pojav_environ->dalvikJNIEnvPtr_ANDROID = env;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user