2015-04-21 26 views
0

我正在试用备用信号堆栈(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)。

请告诉我什么地方出了问题或是它的预期行为。

回答

0

我见过有关堆栈的procfs信息不正确的地方。尝试在信号处理程序中打印局部变量的地址。我敢打赌,你会发现你看到的堆栈是主堆栈。

我不知道为什么会发生这种情况,但它看起来像是一个内核事物。我也在Linux上看到过它。