linux多线程环境下的抢尸行为(system返回-1:No child processes)http://www.aiuxian.com/article/p-129935.html

本文解析了Linux环境下多线程程序中出现的“抢尸”现象,即子进程被意外回收导致system函数返回-1的问题。通过深入内核级监控揭示了问题根源,并提供了有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux多线程环境下的抢尸行为(system返回-1:No child processes)

分类: C程序  |  标签: system,抢尸,No child processes,waitpid  |  作者: joseph_1118  相关  |  发布日期 : 2012-06-08  |  热度 : 897°

问题背景:

   我们这边开发了一个动态库给客户用,动态库里面会调用system来做insmod/rmmod的操作。拿到客户那边去测试,会随机性的出现system返回-1的问题,也就是system出错了!但是奇怪的是我们在system返回-1后去lsmod发现实际上insmod/rmmod是成功了的。把当时的errno和对应的出错信息打出来发现errno是10(ECHILD),对应的信息是No child processes。


问题定位:

   早就听说过system函数不靠谱,一方面是安全方面,另一方面是因为其返回值太多,包含不同的含义。近来也确实体会到了这一点,有一次system出错返回的错误码是一个比较大的值,当时错误原因是因为用户的进程里的环境变量是NULL,导致system里面shell的环境变量是NULL,而当时我system是这样写的:system("rmmod xx.ko");直接导致找不到rmmod!后来弄了个绝对路径才解决问题。

   system返回-1,错误码为errno这个问题在google上搜一下,结果一大把,但是基本都是说SIGCHILD的处理方式设置为SIG_IGN的问题。所以,一开始我们也怀疑是这个问题。毕竟我们的so是在客户的环境上用的,我们不清楚客户到底有没有忽略(我们也不是很信任客户的承诺 :))。但是,由于这个是概率性问题,我们猜测可能是客户的某个线程在某个时候会去做这个事情。所以,我这边写了一个jprobe,监控内核的do_sigaction,看看是否有谁去把SIGCHLD的处理方式显式地修改成SIG_IGN。后来重现了问题,但是jprobe没抓到数据。显然,并不是忽略SIGCHLD导致的该问题。

    到这个地步就只能再去看内核代码,有没有其他可能导致返回ECHILD。最后发现,如果找不到子进程的尸体,那么也会返回ECHILD。其实从错误提示“No child processes”也早应该想到...

    我们可以确定,子进程创建是成功的,而且子进程的活也干了,显然子进程出生过。后来,子进程完成了任务,然后死去了,成为一具僵尸。而父进程这时应该去给子进程收尸,但是,子进程的尸体没了!!!!多么恐怖的一件事情惊恐!子进程的尸体到底被谁抢走了?难道有人捞回去搞阴婚了吗?想想都觉得毛骨悚然~~

    有问题定位思路就是好事,至少有希望了。继续jprobe...这次是在wait_consider_task中,看看谁回去查看这具尸体。感觉就像安排个小人儿在尸体附近的草丛中,看看谁会偷偷摸摸地去打那具尸体的主意。惊恐

    这次结果没有让我们失望,发现有个进程会很频繁地去干这种龌龊的事情!把这个进程的名字以及其父进程的名字发给客户,询问他们到底是什么关系,为什么要干这事。最终发现是这样的场景:

    也就是说,客户是在线程2中调用我们的so,但是他们的线程1里面在周期性地做waitpid(-1)的事情(他们以为他们的task A只有一个子进程,所以不加选择的用了-1去回收子进程)。然后,在某个时刻,线程2的子进程的尸体被线程1收走了。然后线程2的system就出错了。抢尸就是这么发生的。后来,客户那边把waitpid的第一个参数改成他的子进程的pid就好了。

    本文大致描述了这个问题的过程,后面我会详细分析SIGCHLD的作用,以及什么情况下会出现ECHILD错误。欢迎指正!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值