linux信号处理

linux在构造信号处理过程中面临内核态触发用户态代码的问题。当信号到达内核,内核不可能直接执行用户态的代码。所以,内核利用的方式是将用户态进程的栈帧扩展,然后直接返回用户态,利用伪造的栈信息执行信号量。

这是内核给用户态的程序提供的一个接口。
arch/arm64/kernel/vdso/vdso.lds.S

ENTRY(__kernel_rt_sigreturn)
    .cfi_startproc
        .cfi_signal_frame
        .cfi_def_cfa    x29, 0
        .cfi_offset     x29, 0 * 8
        .cfi_offset     x30, 1 * 8
        mov     x8, #__NR_rt_sigreturn
        svc     #0
        .cfi_endproc
ENDPROC(__kernel_rt_sigreturn)

__kernel_rt_sigreturn,做一个系统调用,查询系统调用表,对应的函数是sys_rt_sigreturn

arm下面利用vdso __kernel_rt_sigreturn恢复保存的用户态栈信息,

- [Depth] [Result]  [VA]  [RVA]  [Sym]   [Img]
        0  80000003  7FA03F4F0C  BFF0C  <unknown>   /lib/aarch64-linux-gnu/libc-2.23.so
        1  80000003  7FA06C933C  533C  <unknown>   /usr/lib/aarch64-linux-gnu/libdrm.so.2.4.0
        2  80000003  7FA06CFD8C  BD8C  <unknown>   /usr/lib/aarch64-linux-gnu/libdrm.so.2.4.0
        3  80000003  7F9FCD2A4C  50A4C  <unknown>   /usr/lib/xorg/modules/drivers/radeon_drv.so
        4  80000003  5579F67138  CC138  <unknown>   /usr/lib/xorg/Xorg
        5  80000003  557A036C74  19BC74  <unknown>   /usr/lib/xorg/Xorg
        6  80000003  557A0378E0  19C8E0  <unknown>   /usr/lib/xorg/Xorg
        7  80000003  5579F06740  6B740  <unknown>   /usr/lib/xorg/Xorg
        8  80000003  5579F06D54  6BD54  <unknown>   /usr/lib/xorg/Xorg
        9  80000003  5579F08308  6D308  <unknown>   /usr/lib/xorg/Xorg
        10  80000003  5579F0873C  6D73C  <unknown>   /usr/lib/xorg/Xorg
        11  80000003  7F9FC35178  6178  <unknown>   /usr/lib/xorg/modules/input/evdev_drv.so
        12  80000003  7F9FC35808  6808  <unknown>   /usr/lib/xorg/modules/input/evdev_drv.so
        13  80000003  5579F300D0  950D0  <unknown>   /usr/lib/xorg/Xorg
        14  80000003  5579F53E94  B8E94  <unknown>   /usr/lib/xorg/Xorg
        15  80000004  7FA089E6C0  6C0  <unknown>   <unknown>
        16  10000000  7FA03F56AC  C06AC  <unknown>   /lib/aarch64-linux-gnu/libc-2.23.so
        17  10000000  557A046098  1AB098  <unknown>   /usr/lib/xorg/Xorg
        18  10000000  5579EF00F4  550F4  <unknown>   /usr/lib/xorg/Xorg
        19  10000000  5579EF43EC  593EC  <unknown>   /usr/lib/xorg/Xorg
        20  10000000  7FA0354920  1F920  <unknown>   /lib/aarch64-linux-gnu/libc-2.23.so
        21  10000000  5579EDDFF8  42FF8  <unknown>   /usr/lib/xorg/Xorg

整个栈会在 va 6c0执行栈恢复,在网上的栈其实信号处理函数的栈。当返回va 6c0栈信息恢复到信号触发前,进程继续运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信号处理Linux系统中的一个重要概念,用于处理进程间通信和异常情况。信号是由操作系统或其他进程发送给进程的通知,用于通知进程发生了某个事件或异常情况。信号可以被进程捕获和处理,也可以被忽略或使用默认处理方式。 在Linux中,信号可以由多种情况触发,比如按下CTRL+C键产生的SIGINT信号,非法内存访问产生的信号,硬件故障产生的信号,以及环境切换等。进程可以通过调用signal函数来注册信号处理函数,以捕获和处理特定的信号。 signal函数的原型如下: ```c typedef void (*sighandler)(int); sighandler signal(int signum, sighandler handler); ``` 其中,signum是需要处理的信号编号,handler是信号的处理函数。处理函数可以是用户自定义的函数,也可以是预定义的常量SIG_IGN表示忽略该信号,或者SIG_DFL表示使用默认的信号处理方式。 在信号处理函数中,可以执行一些特定的操作来处理信号,比如打印日志、保存数据、发送信号给其他进程等。处理函数可以是空函数,表示仅仅捕获信号但不做任何处理。 需要注意的是,一个进程可以屏蔽掉大多数的信号,除了SIGSTOP和SIGKILL这两个信号是无法被屏蔽的。信号有优先级,当一个进程有多个未决信号时,内核将按照发送的顺序来递送信号。值越小的信号越先被递送。 在Linux中,可以通过编写信号处理程序来处理不同的信号,并根据需要执行特定的操作。通过信号处理,可以实现进程间通信、优雅地关闭进程或处理异常情况等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值