借助GDB探究sigaction结构体的内部构成
调试背景信息
已通过GDB定位到sigaction调用的PLT指令:
0x73xxxxxxxx: bl 0x73xxxxxxxx <sigaction@plt>
调用时寄存器参数如下:
x0 0x0e 14 x1 0x7fxxxxxxxx xxxxxxxxxxxx x2 0x0
进一步查看x1指向的内存内容:
(gdb) x/16gx 0x7fxxxxxxxx 0x7fe5xxxxc0: 0x0000000000000004 0x0000007365xxxxxx 0x7fe5xxxxd0: 0xffffffffffffffff 0x0000000000000000 0x7fe5xxxxe0: 0x0000000000000020 0x0000003800030015 0x7fe5xxxxf0: 0x0000003800020015 0x0000003800010015 0x7fe5xxxxx0: 0x000000380f000015 0x0000000c00000020 0x7fe5xxxx10: 0x0000007300020015 0x0000007304000025 0x7fe5xxxx20: 0x000000730b030025 0x0000000800000020
(注:内存地址末尾的xxxxx0应为输入笔误,实际应为连续递增的地址)
参数疑问解答
- x0是否对应要处理的信号?
是。ARM64架构下sigaction的第一个参数为信号编号,0x0e即十进制14,对应SIGALRM信号。 - x1是否为新的sigaction结构体?
是。sigaction的第二个参数是指向新配置的struct sigaction结构体的指针,用于设置目标信号的处理规则。 - x2是否为旧的sigaction结构体(即未定义旧结构体?)
x2的值为0,说明调用者不需要保存该信号之前的处理配置,即传入了NULL,无需获取旧的sigaction信息。
结构体字段与内存qword的映射
已知第二个qword(地址0x7fe5xxxxc8,值0x0000007365xxxxxx)是信号处理函数,结合ARM64 Linux下struct sigaction的内存布局,各qword的映射如下:
地址
0x7fe5xxxxc0,值0x0000000000000004
对应sa_flags字段。0x4是SA_RESTART标志位,表示当系统调用被该信号中断时,内核会自动重启该系统调用。地址
0x7fe5xxxxc8,值0x0000007365xxxxxx
对应sa_handler字段(信号处理函数指针),与已知信息一致。由于sa_flags中未设置SA_SIGINFO(标志位为0x40),这里使用的是普通的信号处理函数类型void(*)(int)。地址
0x7fe5xxxxd0,值0xffffffffffffffff地址
0x7fe5xxxxd8,值0x0000000000000000
这两个qword对应sa_mask字段(信号掩码)。sa_mask是sigset_t类型,在ARM64系统中以64位为单位存储,第一个64位全1表示阻塞所有前64个信号,第二个64位全0表示不阻塞后续信号。地址
0x7fe5xxxxe0及之后的qword
从0x7fe5xxxxe0开始的后续字段,对应sa_restorer及sigset_t的扩展部分:
0x0000000000000020为sa_restorer函数指针,用于信号处理完成后恢复栈环境(ARM64环境中glibc会自动设置该字段);- 后续的
0x0000003800030015等数值属于sa_mask的扩展部分,对应超出前64位的信号掩码,每个qword表示64个信号的阻塞状态。
内容的提问来源于stack exchange,提问作者localacct

