Issue #5239 has been updated by Motohiro KOSAKI.

Status changed from Open to Assigned
Assignee set to Motohiro KOSAKI
Target version set to 1.9.3

> The problem is that the call to $? in the thread cannot retrieve the exit value of the process started by popen. "$?" is 
> transformed into a wait4() syscall, but wait4 is not allowed to inquire the state of non-child processes. And the popen
> process is not a child of the sub-thread, it is a child of the main thread.
>
> http://pubs.opengroup.org/onlinepubs/009695399/functions/wait.html confirms that waitpid() is not supposed to work on
> non-child processes.

In fact, it's a child process. see more below paragraph.


> RATIONALE
> A call to the wait() or waitpid() function only returns status on an immediate child process of the *calling process*

The pthread rule is, pthread_create() doen't introduce any process tree change. In the other words, kFreeBSD is buggy.

But I'm planning to commit your patch because 1) it's only test case change and no impact to ruby code base 2) your patch
doesn't introduce any ugliness.



----------------------------------------
Bug #5239: bootstraptest/runner.rb: assert_normal_exit logic broken on Debian/GNU kFreeBSD
http://redmine.ruby-lang.org/issues/5239

Author: Lucas Nussbaum
Status: Assigned
Priority: Normal
Assignee: Motohiro KOSAKI
Category: 
Target version: 1.9.3
ruby -v: 1.9.3


Hi,

assert_normal_exit() breaks on some platforms, such as Debian GNU/kFreeBSD.

It does:

    begin
      $stderr.reopen("assert_normal_exit.log", "w")
      io = IO.popen("#{@ruby} -W0 #{filename}")
      pid = io.pid
      th = Thread.new {
        io.read
        io.close
        $?
      }
      if !th.join(timeout)
        Process.kill :KILL, pid
        timeout_signaled = true
      end
      status = th.value
    ensure
      $stderr.reopen(old_stderr)
      old_stderr.close
    end
    if status.signaled?

The problem is that the call to $? in the thread cannot retrieve the exit value of the process started by popen. "$?" is transformed into a wait4() syscall, but wait4 is not allowed to inquire the state of non-child processes. And the popen process is not a child of the sub-thread, it is a child of the main thread.

http://pubs.opengroup.org/onlinepubs/009695399/functions/wait.html confirms that waitpid() is not supposed to work on non-child processes.

It works on Linux because wait4() is friendlier there and accepts to give the state of non-child processes.

This was introduced in svn revision 26700, when a timeout was added.


-- 
http://redmine.ruby-lang.org