linux信号速成

对信号一直感到很神秘,好像是能够hack的地方,呵呵...

看了看书,感觉其实信号不过是一种类似中断处理机制,
书上说信号是进程(系统进程和用户进程)间通信的方法。在
进程收到信号时,其执行的流程将被系统中断,如经常使用的
Ctrl+C(中断),系统将退出程序。

例如:
divzero.c:

main()
{
    int a,b;
    scanf("%d %d", &a, &b);
    printf("a/b is %d",a/b);
}

如果用3 0来运行的话,系统输入了 “浮点数例外" 的提示。

signal.c:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void signal_handler(int signal) {
    printf("Caught signal %d\n", signal);
    if (SIGTSTP == signal) //Ctrl+Z(Terminal strp)
    {
        printf("SIGTSTP (Ctrl+Z)\n");
    }
   else if (SIGQUIT == signal)
   {
        printf("SIGQUIT (QUIT)\n");
   }
   else if (SIGUSR1 == signal)
   {
        printf("SIGSR1 \n");
   }
   else if (SIGUSR2 == signal)
   {
        printf("SIGSR2 \n");
   }
    
}

void sigint_handler(int x) {      //中断信号处理函数
    printf("Caught a Ctrl + C(SIGINT) in a handler\nExiting\n");
    exit(0);
}

int
main (int argc, char *argv[])
{
    signal(SIGQUIT, sigint_handler); //注册信号处理函数
    signal(SIGTSTP, signal_handler);
    signal(SIGUSR1, signal_handler);
    signal(SIGUSR2, signal_handler);
    
    signal(SIGINT, sigint_handler);
    
    while (1)  //死循环
    {
    ;
    }
    return 0;
}

如果运行时按下Ctrl+C发送一个中断信号,那么出现
^CCaught a Ctrl + C(SIGINT) in a handler
Exiting
程序结束。

此外使用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    
也能通过他发送信号给进程:kill -numberofsignal pid

如果使用strace -p pid就能不停的跟踪进程获得的信号,如运行signal.c:

使用strace 命令:
两次Ctrl+Z后结束 在另一个终端:
Process 6825 attached - interrupt to quit
--- SIGTSTP (Stopped) @ 0 (0) ---
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f4000
write(1, "Caught signal 20\n", 17)      = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17)      = 17
sigreturn()                             = ? (mask now [])
--- SIGTSTP (Stopped) @ 0 (0) ---
write(1, "Caught signal 20\n", 17)      = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17)      = 17
sigreturn()                             = ? (mask now [])
write(1, "Caught a Ctrl + C(SIGINT) in a h"..., 39) = 39
write(1, "Exiting\n", 8)                = 8
exit_group(0)                           = ?
Process 6825 detached

可见strace的强大之处,呵呵...


再如处理一个除数为0的中断:

ZeroInterrupt.c:

#include <signal.h>

void signal_handler (int signal) {
    printf("Something wrong with your program!\n");
    if (signal == SIGFPE) //SIGFPE为算术错误信号
    {
        printf("fate error happen!\n");
    }
    exit(0);
}


int
main (int argc, char *argv[])
{
    signal(SIGFPE, signal_handler);  //注册信号处理函数
    
    int i;
    for (i = -10; i <=10 ; i++) {
        printf("%d div %d is %d\n", i , i , i/i);
     }
    return 0;
}

运行如下:
-10 div -10 is 1
-9 div -9 is 1
-8 div -8 is 1
-7 div -7 is 1
-6 div -6 is 1
-5 div -5 is 1
-4 div -4 is 1
-3 div -3 is 1
-2 div -2 is 1
-1 div -1 is 1
Something wrong with your program!
fate error happen!

看来信号的设计是为了处理一些通用系统(硬件)的问题,来处理编程中的硬伤。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值