Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in signal processing functions #24

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions patrons/src/main/cpp/patrons_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ Java_com_alibaba_android_patronus__1Patrons__1_1init(__unused JNIEnv *env, __unu
LOGE("signal handler reg failed.");
} else {
has_exception_handle_ = true;
LOGI("signal handler reg success, old handler = %p", &sig_act_old[SIGSEGV]);
LOGI("signal handler reg success, old handler = %p", &sig_act_old);
}

int initCode;
Expand Down Expand Up @@ -325,19 +325,20 @@ Java_com_alibaba_android_patronus__1Patrons_shrinkRegionSpace(__unused JNIEnv *e
return false;
}

bool ret = false;
if (ClampGrowthLimit && region_space_) {
if (has_exception_handle_ && !debuggable) {
i_want_handle_signal_flag = 1;
if (0 == sigsetjmp(time_machine, 1)) {
ResizeRegionSpace(new_size * MB);
ret = ResizeRegionSpace(new_size * MB);
} else {
LOGE("resize failed, found exception signal.");
return false;
}

i_want_handle_signal_flag = 0;
} else {
return ResizeRegionSpace(new_size * MB);
ret = ResizeRegionSpace(new_size * MB);
}
} else {
LOGE("resize failed, key param is NULL, instance = %p, method = %p.",
Expand All @@ -347,7 +348,7 @@ Java_com_alibaba_android_patronus__1Patrons_shrinkRegionSpace(__unused JNIEnv *e
return false;
}

return true;
return ret;
}

JNIEXPORT jlong JNICALL
Expand Down
33 changes: 23 additions & 10 deletions patrons/src/main/cpp/patrons_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ bool has_exception_handle_ = false;
/**
* 异常处理
*/
static struct sigaction sig_act_old[16] = {0};
static struct sigaction sig_act_old = {0};
static volatile int i_want_handle_signal_flag = 0;
static sigjmp_buf time_machine;

Expand Down Expand Up @@ -364,37 +364,50 @@ void InitEnv() {
/**
* 自定义异常处理函数
*/
static void CustomSignalHandler(int sig) {
static void CustomSignalHandler(int signum, siginfo_t* siginfo, void* context) {
if (i_want_handle_signal_flag) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "found exception signal %d", sig);
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "found exception signal %d", signum);

// reset flag.
i_want_handle_signal_flag = 0;

siglongjmp(time_machine, 1);
} else {
// use raw log method, LOGE not thread safe.
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "found exception signal %d, but not my business.", sig);
sigaction(sig, &sig_act_old[sig], NULL);
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "found exception signal %d, but not my business.", signum);

// sigaction(sig, &sig_act_old, NULL);
if (sig_act_old.sa_flags & SA_SIGINFO) {
sig_act_old.sa_sigaction(signum, siginfo, context);
} else {
if (SIG_DFL == sig_act_old.sa_handler) {
// If the previous handler was the default handler, cause a core dump.
signal(signum, SIG_DFL);
raise(signum);
} else if (SIG_IGN == sig_act_old.sa_handler) {
return;
} else {
sig_act_old.sa_handler(signum);
}
}
}
}

/**
* 覆盖特定信号的处理函数
*/
static int HandleSignal(int sig) {
struct sigaction act, handler;
struct sigaction act = {0};

if (0 != sigemptyset(&act.sa_mask))
return (0 == errno ? SIGNAL_HANDLER_REG_ERROR : errno);

act.sa_handler = CustomSignalHandler;
act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
act.sa_sigaction = CustomSignalHandler;

if (0 != sigaction(sig, &act, &handler))
if (0 != sigaction(sig, &act, &sig_act_old))
return (0 == errno ? SIGNAL_HANDLER_REG_ERROR : errno);

sig_act_old[sig] = handler;

return 0;
}

Expand Down
26 changes: 20 additions & 6 deletions patrons/src/main/cpp/xhook/xh_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,37 @@ static int xh_core_sigsegv_enable = 1; //enable by default
static struct sigaction xh_core_sigsegv_act_old;
static volatile int xh_core_sigsegv_flag = 0;
static sigjmp_buf xh_core_sigsegv_env;
static void xh_core_sigsegv_handler(int sig)
static void xh_core_sigsegv_handler(int signum, siginfo_t* siginfo, void* context)
{
(void)sig;

if(xh_core_sigsegv_flag)
siglongjmp(xh_core_sigsegv_env, 1);
else
sigaction(SIGSEGV, &xh_core_sigsegv_act_old, NULL);
{
// sigaction(SIGSEGV, &xh_core_sigsegv_act_old, NULL);
if (xh_core_sigsegv_act_old.sa_flags & SA_SIGINFO) {
xh_core_sigsegv_act_old.sa_sigaction(signum, siginfo, context);
} else {
if (SIG_DFL == xh_core_sigsegv_act_old.sa_handler) {
// If the previous handler was the default handler, cause a core dump.
signal(signum, SIG_DFL);
raise(signum);
} else if (SIG_IGN == xh_core_sigsegv_act_old.sa_handler) {
return;
} else {
xh_core_sigsegv_act_old.sa_handler(signum);
}
}
}
}
static int xh_core_add_sigsegv_handler()
{
struct sigaction act;
struct sigaction act = {0};

if(!xh_core_sigsegv_enable) return 0;

if(0 != sigemptyset(&act.sa_mask)) return (0 == errno ? XH_ERRNO_UNKNOWN : errno);
act.sa_handler = xh_core_sigsegv_handler;
act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
act.sa_sigaction = xh_core_sigsegv_handler;

if(0 != sigaction(SIGSEGV, &act, &xh_core_sigsegv_act_old))
return (0 == errno ? XH_ERRNO_UNKNOWN : errno);
Expand Down