加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

waitpid – WIFEXITED返回0虽然孩子正常退出

发布时间:2020-12-16 09:51:56 所属栏目:百科 来源:网络整理
导读:我一直在编写一个生成子进程的程序,并调用waitpid来等待子进程的终止.代码如下: // fork exec the child pid_t pid = fork(); if (pid == -1) // here is error handling code that is **not** triggered if (!pid) { // binary_invocation is an array of
我一直在编写一个生成子进程的程序,并调用waitpid来等待子进程的终止.代码如下:

// fork & exec the child
  pid_t pid = fork();
  if (pid == -1)
    // here is error handling code that is **not** triggered

  if (!pid)
    {
      // binary_invocation is an array of the child process program and its arguments
      execv(args.binary_invocation[0],(char * const*)args.binary_invocation);
      // here is some error handling code that is **not** triggered
    }
  else
    {
      int status = 0;
      pid_t res = waitpid(pid,&status,0);

      // here I see pid_t being a positive integer > 0
      // and status being 11,which means WIFEXITED(status) is 0.
      // this triggers a warning in my programs output.
    }

wap的联机帮助页面为WIFEXITED:

WIFEXITED(status)
    returns  true  if  the child terminated normally,that is,by calling exit(3) or
    _exit(2),or by returning from main().

我的意思是它应该返回一个整数!= 0成功,这在我的程序执行中没有发生,因为我观察到WIFEXITED(状态)== 0

但是,从命令行执行相同的程序会导致$? == 0,从gdb开始导致:

[Inferior 1 (process 31934) exited normally]

程序运行正常,除了触发警告,这让我觉得其他事情正在发生,我不知道.

编辑:
?正如下面评论中所建议的,我检查了孩子是否通过segfault终止,实际上,WIFSIGNALED(status)返回1,WTERMSIG(status)返回11,即SIGSEGV.

我不明白的是,为什么通过execv调用会因为段错误而失败,而通过gdb进行相同的调用,或者shell会成功?

EDIT2:
我的应用程序的行为在很大程度上取决于子进程的行为,特别是在子进程在__attribute __((析构函数)声明的函数中写入的文件中).在waitpid调用返回之后,此文件存在并正确生成,这意味着段错误发生在另一个析构函数中的某个位置,或者在我控制之外的某个位置.

解决方法

在Unix和Linux系统上,wait或waitpid(或任何其他等待变体)返回的状态具有以下结构:

bits   meaning

0-6    signal number that caused child to exit,or 0177 if child stopped / continued
       or zero if child exited without a signal

 7     1 if core dumped,else 0

8-15   low 8 bits of value passed to _exit/exit or returned by main,or signal that caused child to stop/continue

(请注意,Posix不定义位,只定义宏,但这些是至少Linux,Mac OS X / iOS和Solaris使用的位定义.另请注意,如果您通过了WUNTRACED,则waitpid仅返回停止事件如果您传递WCONTINUED标志,则标记和继续事件.)

所以11的状态意味着孩子因信号11退出,这是SIGSEGV(同样,不是Posix,而是传统的).

您的程序是将无效参数传递给execv(这是一个围绕execve的C库包装或其他一些特定于内核的调用),或者当您执行它时以及从shell或gdb运行它时,子进程运行方式不同.

如果您使用的是支持strace的系统,请在strace -f下运行您的(父)程序,以查看execv是否导致信号.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读