c - 为什么像clone()这样的系统调用会失败、恢复和暂停?

标签 c linux linux-kernel kernel

这是我的情况:我正在为操作系统类(class)编写 UNIX |。我完成了我的实现;但是,我注意到我不确定地通过了测试用例。有问题的测试用例的形式如下:

    def test_no_orphans(self):
        self.assertTrue(self.make, msg='make failed')
        subprocess.call(('strace', '-o', 'trace.log','./pipe','ls','wc','cat','cat'))
        ps = subprocess.Popen(['grep','-o','clone(','trace.log'], stdout=subprocess.PIPE)
        out1 = subprocess.check_output(('wc','-l'), stdin=ps.stdout)
        ps.wait()        
        ps.stdout.close()
        ps = subprocess.Popen(['grep','-o','wait','trace.log'], stdout=subprocess.PIPE)
        out2 = subprocess.check_output(('wc','-l'), stdin=ps.stdout)
        ps.wait()  
        ps.stdout.close()
        out1 = int(out1.decode("utf-8")[0])
        out2 = int(out2.decode("utf-8")[0])
        if out1 == out2 or out1 < out2:
            orphan_check = True
        else:
            orphan_check = False
        self.assertTrue(orphan_check, msg="Found orphan processes")
        subprocess.call(['rm', 'trace.log'])
        self.assertTrue(self._make_clean, msg='make clean failed')

检查相关日志后发现:

clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f04174ad850) = 1330
close(4)                                = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1330, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
pipe([4, 5])                            = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f04174ad850) = 1331
close(5)                                = 0
close(3)                                = 0
pipe([3, 5])                            = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f04174ad850) = ? ERESTARTNOINTR (To be restarted)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1331, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f04174ad850) = 1332
close(5)                                = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1332, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
close(4)                                = 0
pipe([4, 5])                            = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f04174ad850) = 1333

具体来说,带有 ERESTARTNOINTR (To be restarted) 的行导致我失败。教授帮我调试后,我向负责作业的助教报告了这个问题,并说这可能是测试用例中的一个错误。

我想知道为什么 clone() 会失败,因为 fork() 似乎在一个很好的 C 包装器中为我们处理了这个问题。我还想知道这里具体发生了什么,以及为什么系统调用通常似乎有一个不完整和一个恢复状态,正如我的操作系统教授所说的那样对此不太了解,他基本上说这可能是“内核中的竞争条件”。

最佳答案

clone(2) 的手册页显示,ERESTARTNOINTR 会在以下情况返回

System call was interrupted by a signal and will be restarted. (This can be seen only during a trace.)

所提供日志中失败的clone系统调用被pid 1331的SIGCHLD信号中断。

关于c - 为什么像clone()这样的系统调用会失败、恢复和暂停?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76069593/

相关文章:

c++ - 确定系统队列中下一个 UDP 数据报的大小

linux - 通过元层覆盖 Yocto 类

linux - 是否可以替换现有字符设备的字符驱动程序?

无法从 Yocto 为 BeagleBone 编译 Linux 内核 DTSI 文件

linux-kernel - 重启后如何检测内核 panic

c - 无法避免子进程继承父进程的 cpu 亲和性

c - 如何在 C 中使用 extern?

将变量转换为 int vs round() 函数

Linux内核错误?创建新套接字默认为非阻塞

c - self 实现 strcat 显示多个字符串