Я экспериментирую с альтернативным стеком сигналов (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, если этот флаг установлен, 8 КБ стека выделяются следующим образом (SIGSTKSZ = 0x2000(8 КБ)):
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;
}
В этом случае я не полагаюсь на то, что bionic выделит мне стек по умолчанию. Я выделяю свой собственный стек и использую его.
Итак, в обоих этих случаях я выделяю стеки сигналов по 8 КБ.
Я поставил внутренний обработчик сигнала 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]
Странно то, что, хотя я выделил только 8 КБ стека с помощью malloc() в методе 2, стек, похоже, выделил около 2 МБ (0x200000).
Пожалуйста, сообщите мне, что пошло не так, или это ожидаемое поведение.