我正在試用備用信號堆棧(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)。
請告訴我什麼地方出了問題或是它的預期行爲。