2015-04-21 23 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上看到過它。