zoukankan      html  css  js  c++  java
  • Linux 信号(三)—— sigaction 函数

    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 options
    10   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环境高级编程》

  • 相关阅读:
    scala 基础
    Feign拦截器和解码器
    SpringCloud对使用者透明的数据同步组件
    POI SXSSF API 导出1000万数据示例
    HDFS文件浏览页返回上级目录功能
    Spring Security OAuth2.0
    Spring Security实现OAuth2.0授权服务
    Spring Security实现OAuth2.0授权服务
    Zookeeper学习笔记:简单注册中心
    Eclipse集成Git做团队开发:分支管理
  • 原文地址:https://www.cnblogs.com/ilocker/p/4717879.html
Copyright © 2011-2022 走看看