Skip to content

Commit

Permalink
Tweak[jre_launcher]: even better sigabrt reporting(maybe)
Browse files Browse the repository at this point in the history
  • Loading branch information
artdeell committed Jan 23, 2025
1 parent 88cadf9 commit 91b6820
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
2 changes: 1 addition & 1 deletion app_pojavlauncher/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ dependencies {
// Our version of exp4j can be built from source at
// https://github.com/PojavLauncherTeam/exp4j
implementation 'net.sourceforge.htmlcleaner:htmlcleaner:2.6.1'
implementation 'com.bytedance:bytehook:1.0.9'
implementation 'com.bytedance:bytehook:1.1.1'

// implementation 'net.sourceforge.streamsupport:streamsupport-cfuture:1.7.0'

Expand Down
19 changes: 18 additions & 1 deletion app_pojavlauncher/src/main/jni/exit_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ static void custom_atexit() {
nominal_exit(0, false);
}

typedef void (*android_set_abort_message_t)(const char* msg);

// Writes a string constant into stdout in a signal-safe fashion
#define PRINT_SIGSAFE(x) do { \
const char *msg = x; \
write(STDOUT_FILENO, msg, sizeof(msg));\
} while(0)

static void custom_set_abort_message(const char* amsg) {
PRINT_SIGSAFE("Abort message: ");
PRINT_SIGSAFE(amsg);
PRINT_SIGSAFE("\n");
BYTEHOOK_CALL_PREV(custom_set_abort_message, android_set_abort_message_t, amsg);
BYTEHOOK_POP_STACK();
}

static bool init_exit_hook() {
void* bytehook_handle = dlopen("libbytehook.so", RTLD_NOW);
if(bytehook_handle == NULL) {
Expand All @@ -56,7 +72,8 @@ static bool init_exit_hook() {
int bhook_status = bytehook_init_p(BYTEHOOK_MODE_AUTOMATIC, false);
if(bhook_status == BYTEHOOK_STATUS_CODE_OK) {
bytehook_stub_t stub = bytehook_hook_all_p(NULL, "exit", &custom_exit, NULL, NULL);
__android_log_print(ANDROID_LOG_INFO, "exit_hook", "Successfully initialized exit hook, stub=%p", stub);
bytehook_stub_t stub2 = bytehook_hook_all_p(NULL, "android_set_abort_message", &custom_set_abort_message, NULL, NULL);
__android_log_print(ANDROID_LOG_INFO, "exit_hook", "Successfully initialized exit hook, stub=%p %p", stub, stub2);
return true;
} else {
__android_log_print(ANDROID_LOG_INFO, "exit_hook", "bytehook_init failed (%i)", bhook_status);
Expand Down
19 changes: 10 additions & 9 deletions app_pojavlauncher/src/main/jni/jre_launcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,16 @@ _Noreturn static void* abort_waiter_thread(void* extraArg) {
}
static bool signal_vm_first = true;

// Writes a string constant into stdout in a signal-safe fashion
#define PRINT_SIGSAFE(x) do { \
const char msg[] = x; \
write(STDOUT_FILENO, msg, sizeof(msg));\
} while(0)
int (*JVM_HANDLE_XXX_SIGNAL)(int sig, siginfo_t* info,
void* ucVoid, int abort_if_unrecognized);

_Noreturn static void abort_waiter_handler(int signal) {
_Noreturn static void abort_waiter_siginfo(int signal, siginfo_t* siginfo, void* ucVoid) {
if(signal_vm_first) {
signal_vm_first = false;
// This is nasty and evil, but does work
PRINT_SIGSAFE("SIGABRT occured! Raising SIGSEGV to generate backtrace\n");
raise(SIGSEGV);
JVM_HANDLE_XXX_SIGNAL(signal, siginfo, ucVoid, 1);
// We are supposed to die after this but yeah
while(1) {}
}
// Write the final signal into the pipe and block forever.
write(abort_waiter_data.pipe[1], &signal, sizeof(int));
Expand All @@ -112,7 +110,8 @@ static void abort_waiter_setup() {
sigemptyset(&abort_waiter_data.tracked_sigset);
for(size_t i = 0; i < ntracked; i++) {
sigaddset(&abort_waiter_data.tracked_sigset, tracked_signals[i]);
sigactions[i].sa_handler = abort_waiter_handler;
sigactions[i].sa_sigaction = abort_waiter_siginfo;
sigactions[i].sa_flags = SA_SIGINFO | SA_ONSTACK;
}
if(pipe(abort_waiter_data.pipe) != 0) {
printf("Failed to set up aborter pipe: %s\n", strerror(errno));
Expand All @@ -136,6 +135,8 @@ static void abort_waiter_setup() {

static jint launchJVM(int margc, char** margv) {
void* libjli = dlopen("libjli.so", RTLD_LAZY | RTLD_GLOBAL);
void* libjvm = dlopen("libjvm.so", RTLD_NOLOAD);
JVM_HANDLE_XXX_SIGNAL = dlsym(libjvm, "JVM_handle_linux_signal");

// Unset all signal handlers to create a good slate for JVM signal detection.
struct sigaction clean_sa;
Expand Down

0 comments on commit 91b6820

Please sign in to comment.