我正在试用备用信号堆栈(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
发送信号后的过程。
下面是结果:
方法1(堆栈通过仿生在在pthread_create分配):
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)。
请告诉我什么地方出了问题或是它的预期行为。