我正在尝试替代信号堆栈(man sigaltstack
).
两段代码分配堆栈的方式不同:
int method1(void)
{
struct sigaction act, oldact;
memset(&act, 0, sizeof(act));
act.sa_sigaction = SignalHandler;
act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
sigemptyset(&act.sa_mask);
if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
ALOGW("sigaction failed %s\n", strerror(errno));
return -errno;
}
return 0;
}
我在注册信号时只是使用了 SA_ONSTACK 。当信号线程被调度时,在 pthread_create 中,如果设置了该标志,则会分配 8kb 的堆栈,如下所示(SIGSTKSZ = 0x2000(8kb)):
ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (ss.ss_sp != MAP_FAILED) {
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
sigaltstack(&ss, NULL);
thread->alternate_signal_stack = ss.ss_sp;
}
另一种做同样事情的方法,同时注册信号处理程序。
int method2(void)
{
struct sigaction act, oldact;
stack_t ss;
ss.ss_sp = malloc(SIGSTKSZ);
if (ss.ss_sp == NULL)
return -ENOMEM;
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
sigaltstack(&ss, NULL);
memset(&act, 0, sizeof(act));
act.sa_sigaction = SignalHandler;
act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
sigemptyset(&act.sa_mask);
if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
ALOGW("sigaction failed %s\n", strerror(errno));
return -errno;
}
return 0;
}
在这种情况下,我不依赖仿生来为我分配默认堆栈。我正在分配自己的堆栈并使用它。
因此,在这两种情况下,我都分配 8kb 的信号堆栈。
我已经放了一个while(1)
内部信号处理程序并检查proc/pid/maps
向进程发送信号后。
结果如下:
方法一(pthread_create中bionic分配的栈):
7faa8d1000-7faa8d3000 rw-p 00000000 00:00 0 [stack:6633]
方法2(应用程序使用malloc分配堆栈):
7fb7300000-7fb7500000 rw-p 00000000 00:00 0 [stack:6567]
奇怪的是,虽然我在 method2 中使用 malloc() 只分配了 8kb 堆栈,但堆栈似乎分配了大约 2MB(0x200000)。
请告诉我出了什么问题或者这是预期的行为。