Linux-linux信号处理函数栈如何安排
一个最简单的Linux信号处理程序:
#include <signal.h>
#include <stdio.h>
static void sig_usr(int signo)
{
if (signo == SIGUSR1)
printf("received SIGUSR1n");
}
int main()
{
signal(SIGUSR1, sig_usr);
while (1)
pause();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
《UNIX高级编程第二版》里涉计到信号处理函数,是否是可重入函数,这部分会影响到函数栈的分配。
这个可能和编译器或者系统相关, 比如我的freebsd里debug可以看到:
Breakpoint 1, main () at signal.c:9
9 int main(){
(gdb) info f
Stack level 0, frame at 0xbfbfec60:
eip = 0x8048490 in main (signal.c:9); saved eip 0x80483f9
source language c.
Arglist at 0xbfbfec58, args:
Locals at 0xbfbfec58, Previous frame's sp is 0xbfbfec60
Saved registers:
eip at 0xbfbfec5c
Breakpoint 2, sig_usr (signo=30) at signal.c:5
5 if(signo==SIGUSR1)
(gdb) info f
Stack level 0, frame at 0xbfbfe8c0:
eip = 0x8048476 in sig_usr (signal.c:5); saved eip 0xbfbfffb4
called by frame at 0xbfbfe8c4
source language c.
Arglist at 0xbfbfe8b8, args: signo=30
Locals at 0xbfbfe8b8, Previous frame's sp is 0xbfbfe8c0
Saved registers:
ebp at 0xbfbfe8b8, eip at 0xbfbfe8bc
(gdb) bt
#0 sig_usr (signo=30) at signal.c:5
#1 <signal handler called>
#2 0x280d6a3b in sigsuspend () from /lib/libc.so.7
#3 0x280d5290 in sigpause () from /lib/libc.so.7
#4 0x280cb6a6 in pause () from /lib/libc.so.7
#5 0x080484ba in main () at signal.c:12
可以看到main和sig_usr的栈帧地址没有在一起(0xbfbfec60, 0xbfbfe8c0)
信号处理函数的栈在用户栈是肯定的。
他的栈放在哪和异步执行应该也没啥关系。倒是因为要考虑还有可能被其他信号打断的情况,防止内核栈数据丢失,内核会把一些信息也保存在用户栈中。内核设置好ESP后,用户程序接着用就行了。
信号处理函数返回后,统一再交给内核,根据刚才保存在用户栈的信息,恢复到之前的状态。