ilocker:關注 Android 安全(新入行,0基礎) QQ: 2597294287
1 #include <signal.h>2 int sigaction(int signo, const struct sigaction* act, struct sigaction* oact);
sigaction 用來設置或修改指定信號的 action (處理動作)。若參數 oact 非空,則系統會通過其返回 old action。
struct sigaction 在 android(-arm) 下的定義:
1 struct sigaction { 2 union { 3 //addr of signal handler or SIG_IGN, or SIG_DFL 4 void (*_sa_handler)(int signo); 5 //alternate(替代的) handler 6 void (*_sa_sigaction)(int signo, struct siginfo *info, void *context); 7 } _u; 8 sigset_t sa_mask; //additional signals to block 9 unsigned long sa_flags; //signal options10 void (*sa_restorer)(void); 11 };參數 sa_mask 指定一個信號集,當信號處理程序被調用時,系統會阻塞這些信號。并且當前信號(參數 signo 指定)會被自動加入到這個信號集,這樣保證了在處理指定的信號時,如果該信號再次發生,它會被阻塞,直到前一個信號處理結束。
參數 sa_flags 可以指定一些選項,如:SA_SIGINFO、SA_ONSTACK、SA_RESTART、SA_RESTORER。
如果設置了 SA_SIGINFO,則表示使用 _sa_sigaction信號處理程序 (默認是_sa_handler),通過參數 info 能夠得到一些產生信號的信息。比如struct siginfo中有一個成員 si_code,當信號是 SIGBUS 時,如果 si_code 為 BUS_ADRALN,則表示“無效的地址對齊”。
SA_RESTORER 與 sa_restorer 配對使用,貌似也是為了返回舊的信號處理程序,但現在應該是已經棄用了。
SA_ONSTACK 表示使用一個替代棧。具體有什么作用,可以參考 stackoverflow 上的一個帖子:
ASK:When the signal is delivered, the signal handler is executed on the stack of the PRocess. If SA_ONSTACK is used in sigaction(), then a different stack is used.
What is the use of using different stack? Any use case example?
ANSWER:One use of an alternate stack is to try and handle SIGSEGV properly.
If your process just received a SIGSEGV because it exceeded its stack limit, you can't run the signal handler on the process's stack - it's full already. Having an alternate stack allows you to (carefully) run some more or less graceful shutdown in that case.
SA_RESTART:使被信號中斷的系統調用能夠重新發起。
實際上前面學習的 signal 函數,通常內部也是調用 sigaction 來實現的,android 系統也是這樣:
1 sighandler_t _signal(int signum, sighandler_t handler, int flags) { 2 struct sigaction sa; 3 sigemptyset(&sa.sa_mask); 4 sa.sa_handler = handler; 5 sa.sa_flags = flags; 6 7 if (sigaction(signum, &sa, &sa) == -1) { 8 return SIG_ERR; 9 }10 return (sighandler_t) sa.sa_handler;11 }12 13 sighandler_t signal(int signum, sighandler_t handler) {14 return _signal(signum, handler, SA_RESTART);15 }最后,sigaction 函數的一個使用示例:
1 void set_signal_handler() { 2 struct sigaction action; 3 memset(&action, 0, sizeof(action)); 4 5 sigemptyset(&action.sa_mask); 6 action.sa_sigaction = debuggerd_signal_handler; 7 action.sa_flags = SA_RESTART | SA_SIGINFO; 8 9 //Use the alternate signal stack if available so we can catch stack overflows.10 action.sa_flags |= SA_ONSTACK;11 sigaction(SIGSEGV, &action, NULL);12 }學習資料: 《unix環境高級編程》
新聞熱點
疑難解答