Linux多进程12-信号

信号概念

  • 信号是 Linux 进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。
  • 发往进程的诸多信号,通常都是源于内核。引发内核为进程产生信号的各类事件如下:
    • 对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号。比如输入Ctrl+C通常会给进程发送一个中断信号。
    • 硬件发生异常,即硬件检测到一个错误条件并通知内核,随即再由内核发送相应信号给相关进程。比如执行一条异常的机器语言指令,诸如被 0 除,或者引用了无法访问的内存区域。
    • 系统状态变化,比如 alarm 定时器到期将引起 SIGALRM 信号,进程执行的 CPU
      时间超限,或者该进程的某个子进程退出。
    • 运行 kill 命令或调用 kill 函数。
  • 使用信号的两个主要目的是:
    • 让进程知道已经发生了一个特定的事情。
    • 强迫进程执行它自己代码中的信号处理程序。
  • 信号的特点:
    • 简单
    • 不能携带大量信息
    • 满足某个特定条件才发送
    • 优先级比较高
  • 查看系统定义的信号列表:kill –l
    • 前 31 个信号为常规信号,其余为实时信号。
$kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

image

image

image

信号的5种默认处理动作

  • 查看信号的详细信息:man 7 signal
  • 信号的 5 中默认处理动作
    • Term 终止进程
    • Ign 当前进程忽略掉这个信号
    • Core 终止进程,并生成一个Core文件
    • Cont 继续执行当前被暂停的进程
  • 信号的几种状态:产生、未决、递达
  • SIGKILL 和 SIGSTOP 信号不能被捕捉、阻塞或者忽略,只能执行默认动作。

Core的处理动作演示

一段实例代码

#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    /* code */
    char *buf;            //野内存
    strcpy(buf, "hello"); // err

    return 0;
}

运行

$./a.out 
段错误 (核心已转储)

显示目前资源限制的设定

$ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7224
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1048576
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7224
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

修改 core file size

$ulimit -c 1024
$ulimit -a
core file size          (blocks, -c) 1024
data seg size           (kbytes, -d) unlimited
...
...

运行a.out 生成core文件

$gcc core.c -g
$./a.out 
段错误 (核心已转储)

进入gdb

$gdb a.out
...
...
(gdb) core-file core
[New LWP 2599]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000559e86c2613c in main (argc=1, argv=0x7ffdad8b7588) at core.c:8
8           strcpy(buf, "hello"); // err

SIGSEGV信号: 访问了非法内存, 在第8行发现这个错误

所以, core文件的作用是终止进程, 并生成一个core文件

posted @ 2023-05-17 18:39  言叶以上  阅读(28)  评论(0编辑  收藏  举报