I am experimenting on alternate signal stack(man sigaltstack
).
Two pieces of code allocating stack differently:
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;
}
I have simply used SA_ONSTACK while registering the signal. While the signal thread is being scheduled, in pthread_create, if this flag is set, a 8kb of stack is allocated as follows (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;
}
Another way of doing the same thing, all while registering the signal handler.
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;
}
In this case, I am not relying on bionic to allocate me the default stack. I am allocating my own stack and using it.
So, in both these cases I am allocating signal stacks of 8kb.
I have put a while(1)
inside signal handler and checked proc/pid/maps
after sending a signal to the process.
Here are the results :
Method 1 (stack allocated by bionic in pthread_create):
7faa8d1000-7faa8d3000 rw-p 00000000 00:00 0 [stack:6633]
Method 2 (stack allocated using malloc by the application):
7fb7300000-7fb7500000 rw-p 00000000 00:00 0 [stack:6567]
The strange thing is that while I allocated only 8kb of stack using malloc() in method2, the stack seems to have allocated around 2MB(0x200000).
Kindly advice me on what went wrong or is it expected behaviour.
I've seen times where the information in procfs regarding the stack is incorrect. Try printing the address of a local variable in the signal handler. My bet is that you will find the stack you're seeing is the main stack.
I don't know why this happens but it looks like it's a kernel thing. I've seen it on Linux too.