linux捕获信号处理,linux 捕获信号处理中遇到的死锁

tag: 信号 signal  sigchld  死锁 堆栈

我们的程序需要捕获信号自己处理,所以尝试对1-32的信号处理(后面33-64的信号不处理)。

但是在调试代码时,发现一个线程死锁的问题。

程序目的:捕获信号,然后打印堆栈。

Thread 12 (Thread 0xf7dd2b90 (LWP 5770)):

以下是一个让我觉得奇怪的堆栈,奇怪之处:

1.死锁了:__lll_lock_wait_private

2.获得了2个信号:,为什么不是一个一个信号处理

堆栈如下:

#18 0x0804fa02 in boom ()

boom()是我写的一个制造崩溃的函数:

char *pBoom = NULL;

memcpy( pBoom, "aaaa", 100 );

#16

触发信号

#15 0x080f9844 in TsSigHandler(int, siginfo*, void*) ()

TsSigHandler是信号处理函数。通过以下代码设置:

struct sigaction sigact;

sigemptyset( &sigact.sa_mask );

sigact.sa_flags = SA_ONESHOT | SA_SIGINFO;

sigact.sa_sigaction = TsSigHandler;

信号触发后,由TsSigHandler函数处理

#14 0x080f95c1 in PrintStack() ()

TsSigHandler函数中调用PrintStack函数打印堆栈。

#13 0x00317ead in system () from /lib/libpthread.so.0

PrintStack函数中调用了system函数做一些额外的事情,例如执行gcore(事实证明,这种方法是有点问题的)。

#11 0x001f8132 in do_system () from /lib/libc.so.6

system调用了do_system

#10 0x001eb1a9 in sigprocmask () from /lib/libc.so.6

do_system调用sigprocmask

#8 

关键来了:这是获取到了另外一个信号:SIGCHLD。

#7  0x080f9844 in TsSigHandler(int, siginfo*, void*) ()

又调用信号处理函数TsSigHandler

#3  0x001f7f8b in do_system () from /lib/libc.so.6

system调用do_system,调用流程和上面当然是一样的

#2  0x001f8448 in _L_lock_124 () from /lib/libc.so.6

#1  0x002a0783 in __lll_lock_wait_private () from /lib/libc.so.6

nice!锁住了。。

分析:

system()函数执行的大体过程是:fork()->exec()->waitpid(),

waitpid用于等待子进程执行完毕。

但是在子进程执行完毕时,会产生SIGCHLD信号,

而SIGCHLD信号会唤醒wait中的进程,这就是看到了2个信号的原因,

解决方法:

1.忽略SIGCHLD信号:其实这个信号一般情况下应该被忽略,除非你的程序需要对这种情况做非常特殊的处理

2.不要在这里调用system()

to do: 有空了记得补详细些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值