Skip to content

Close stdin before terminating a timed-out memory leak child - #37

Merged
k0kubun merged 2 commits into
ruby:masterfrom
wtn:ci
Oct 27, 2026
Merged

k0kubun merged 2 commits into
ruby:masterfrom
wtn:ci

Conversation

@wtn

@wtn wtn commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

test_assert_no_memory_leak_applies_timeout_to_sample_range intermittently hangs ruby/ruby's YJIT macOS CI jobs (ruby/ruby master, ruby/ruby#19517).

When the timeout fires during a sample, EnvUtil.terminate sends SIGTERM, but the child's ensure clause then blocks reading "continue" from stdin, which is closed only after terminate returns. terminate escalates to SIGABRT and waits without a time limit, and on CI the aborted child sometimes never exits.

Closing stdin first makes gets return nil, so the child breaks out of the sample loop and exits. The timeout test now checks that the child exited 0 or by SIGTERM; before the fix it was killed by SIGABRT.

With a sample range, assert_no_memory_leak keeps the child's stdin open,
and the child's ensure clause reads a "continue" line from it after each
sample. When the timeout fires while the child is running the sampled
code, EnvUtil.terminate sends SIGTERM, and the child's ensure clause
then blocks reading stdin, which was closed only after terminate
returned. SIGTERM cannot end the child, so terminate escalates to
SIGABRT and then waits for the aborted child without a time limit. On
ruby/ruby's YJIT macOS CI jobs the child sometimes did not exit after
the RUBY_ON_BUG core dump, and the test worker hung until the runner
killed it 20 minutes later. In other runs the test passed but left a
crash report for the child.

Close stdin first. The child's read then returns nil, and its ensure
clause breaks out of the sample loop. The break discards the
SignalException raised by SIGTERM, so the child exits with status 0. If
SIGTERM arrives before the child reaches the sample loop, the child
still dies from SIGTERM.

The existing timeout test now also checks that the child exited
normally or by SIGTERM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@k0kubun k0kubun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks 🙏

@k0kubun

k0kubun commented Oct 27, 2026

Copy link
Copy Markdown
Member

I appreciate the in_p.close fix but the test fix doesn't seem to pass in some environments. Let me merge only the in_p.close part for now.

@k0kubun
k0kubun merged commit ce7a92e into ruby:master Oct 27, 2026
38 checks passed
matzbot pushed a commit to ruby/ruby that referenced this pull request Oct 27, 2026
timed-out memory leak child
(ruby/test-unit-ruby-core#37)

* Close stdin before terminating a timed-out memory leak child

With a sample range, assert_no_memory_leak keeps the child's stdin open,
and the child's ensure clause reads a "continue" line from it after each
sample. When the timeout fires while the child is running the sampled
code, EnvUtil.terminate sends SIGTERM, and the child's ensure clause
then blocks reading stdin, which was closed only after terminate
returned. SIGTERM cannot end the child, so terminate escalates to
SIGABRT and then waits for the aborted child without a time limit. On
ruby/ruby's YJIT macOS CI jobs the child sometimes did not exit after
the RUBY_ON_BUG core dump, and the test worker hung until the runner
killed it 20 minutes later. In other runs the test passed but left a
crash report for the child.

Close stdin first. The child's read then returns nil, and its ensure
clause breaks out of the sample loop. The break discards the
SignalException raised by SIGTERM, so the child exits with status 0. If
SIGTERM arrives before the child reaches the sample loop, the child
still dies from SIGTERM.

The existing timeout test now also checks that the child exited
normally or by SIGTERM.

ruby/test-unit-ruby-core@ce7a92e724

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wtn

wtn commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Thank you! 👏

@wtn
wtn deleted the ci branch October 27, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants