Linux高级调试与优化——信号量机制与应用程序崩溃

背景介绍

  Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行。

  用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI & POSIX C语言标准),同时提供了其他特性的支持。

  应用程序通常不是直接调用Linux内核的系统调用接口,而是通过glibc库封装的接口间接调用Linux内核系统调用。

信号量机制

  关于Linux信号量机制的原理,建议阅读《Unix环境高级编程》第10章,本博客只是简单介绍其原理。

  信号量是一种软中断,用来实现Linux内核和应用程序之间的异步通信。

  Linux支持大概380种信号量,每一个信号量由一个4字节整形数据表示。可以通过man signals查看所有信号量描述。其中1~32号信号量是从Unix继承而来,33~64是Linux内核定义的信号量。

  信号量处理函数可以在应用程序中自定义,如果没有自定义,则链接glibc中默认的信号量处理函数。应用程序也可以屏蔽指定信号量。

  信号量触发情况有三种:

  1)Linux内核检测到应用程序异常,发送特定的信号量给应用程序,应用程序捕获到信号量后,调用信号量处理函数;

  2)Linux内核因为内部事件而给应用程序发送特定信号,通知应用程序发生了某个事件,如著名的segmentation fault,应用程序捕获到信号量后,调用信号量处理函数;

  3)Linux内核检测到外部事件,如Ctrl+C,Ctrl+Z等,发送特定信号给应用程序,应用程序捕获到信号量后,调用信号量处理函数;

常见信号量介绍

       Signal      Standard   Action   Comment
       ────────────────────────────────────────────────────────────────────────
       SIGABRT      P1990      Core    Abort signal from abort(3)                       SIGABRT信号由abort()系统调用产生,通常是glibc库检测到应用程序异常,主动触发的
       SIGALRM      P1990      Term    Timer signal from alarm(2)
       SIGBUS       P2001      Core    Bus error (bad memory access)               SIGBUS指总线访问错误,通常是因为地址不对齐导致,如奇地址;
       SIGCHLD      P1990      Ign     Child stopped or terminated                      SIGCHLD是子线程终止执行时发送给主进程的信号量
       SIGCLD         -        Ign     A synonym for SIGCHLD
       SIGCONT      P1990      Cont    Continue if stopped
       SIGEMT         -        Term    Emulator trap
       SIGFPE       P1990      Core    Floating-point exception
       SIGHUP       P1990      Term    Hangup detected on controlling terminal
                                       or death of controlling process
       SIGILL       P1990      Core    Illegal Instruction                                        SIGILL非法指令错误,可能是程序跑飞的情况或者不兼容代码
       SIGINFO        -                A synonym for SIGPWR
       SIGINT       P1990      Term    Interrupt from keyboard
       SIGIO          -        Term    I/O now possible (4.2BSD)
       SIGIOT         -        Core    IOT trap. A synonym for SIGABRT
       SIGKILL      P1990      Term    Kill signal                                                   SIGKILL通常是通过kill -9 <pid>手动杀死进程时触发的信号量;
       SIGLOST        -        Term    File lock lost (unused)
       SIGPIPE      P1990      Term    Broken pipe: write to pipe with no
                                       readers; see pipe(7)
       SIGPOLL      P2001      Term    Pollable event (Sys V).
                                       Synonym for SIGIO
       SIGPROF      P2001      Term    Profiling timer expired
       SIGPWR         -        Term    Power failure (System V)
       SIGQUIT      P1990      Core    Quit from keyboard
       SIGSEGV      P1990      Core    Invalid memory reference                       SIGSEGV指非法内存访问,通常出现在栈溢出、野指针或者空指针的情况;
       SIGSTKFLT      -        Term    Stack fault on coprocessor (unused)
       SIGSTOP      P1990      Stop    Stop process
       SIGTSTP      P1990      Stop    Stop typed at terminal
       SIGSYS       P2001      Core    Bad system call (SVr4);
                                       see also seccomp(2)
       SIGTERM      P1990      Term    Termination signal
       SIGTRAP      P2001      Core    Trace/breakpoint trap                             SIGTRAP信号量通常用于进行插桩调试,如gdb调试时插入断点等
       SIGTTIN      P1990      Stop    Terminal input for background process
       SIGTTOU      P1990      Stop    Terminal output for background process
       SIGUNUSED      -        Core    Synonymous with SIGSYS
       SIGURG       P2001      Ign     Urgent condition on socket (4.2BSD)
       SIGUSR1      P1990      Term    User-defined signal 1
       SIGUSR2      P1990      Term    User-defined signal 2
       SIGVTALRM    P2001      Term    Virtual alarm clock (4.2BSD)
       SIGXCPU      P2001      Core    CPU time limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGXFSZ      P2001      Core    File size limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGWINCH       -        Ign     Window resize signal (4.3BSD, Sun)

信号量进阶

  关于自定义Linux信号量处理函数、屏蔽指定信号量等操作,参考《System Programing: Signals》

  信号量处理函数实质上是应用程序发生异常时的一种修复或者调试机制,因为信号量处理不是正常的函数调用,因此它会复用父函数的栈,如果信号量处理函数中发生了异常,系统是没有办法处理的,因此,信号量处理函数必须是安全可靠的。

  自定义的信号量处理函数不可以做信号量同步(防止死锁),但是可以通过call fork起gdb调试器或者写log文件到磁盘。

猜你喜欢

转载自www.cnblogs.com/justin-y-lin/p/11257472.html