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

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错误。欢迎指正!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OS error code 0: Success 操作系统错误代码0:成功 OS error code 1: Operation not permitted 操作系统错误代码1:操作不允许 OS error code 2: No such file or directory 操作系统错误代码2:没有这样的文件或目录 OS error code 3: No such process 操作系统错误代码3:没有这样的过程 OS error code 4: Interrupted system call 操作系统错误代码4:中断的系统调用 OS error code 5: Input/output error 操作系统错误代码5:输入/输出错误 OS error code 6: No such device or address 操作系统错误代码6:没有这样的设备或地址 OS error code 7: Argument list too long 操作系统错误代码7:参数列表太长 OS error code 8: Exec format error 操作系统错误代码8:执行格式错误 OS error code 9: Bad file descriptor 操作系统错误代码9:坏的文件描述符 OS error code 10: No child processes 操作系统错误代码10:无子过程 OS error code 11: Resource temporarily unavailable 操作系统错误代码11:资源暂时不可用 OS error code 12: Cannot allocate memory 操作系统错误代码12:无法分配内存 OS error code 13: Permission denied 操作系统错误代码13:权限被拒绝 OS error code 14: Bad address 操作系统错误代码14:错误的地址 OS error code 15: Block device required 操作系统错误代码15:需要块设备 OS error code 16: Device or resource busy 操作系统错误代码16:设备或资源忙 OS error code 17: File exists 操作系统错误代码17:文件已经存在 OS error code 18: Invalid cross-device link 操作系统错误代码18:无效的跨设备链接 OS error code 19: No such device 操作系统错误代码19:没有这样的设备 OS error code 20: Not a directory 操作系统错误代码20:不是一个目录 OS error code 21: Is a directory 操作系统错误代码21:是一个目录 OS error code 22: Invalid argument 操作系统错误代码22:无效参数 OS error code 23: Too many open files in system 操作系统错误代码23:打开太多的文件系统 OS error code 24: Too many open files 操作系统错误代码24:打开的文件太多 OS error code 25: Inappropriate ioctl for device

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值