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_sigreturnarm下面利用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栈信息恢复到信号触发前,进程继续运行。