Skip to content

Commit edcd803

Browse files
committed
Handle signal-terminated processes in exit status
When a child process is terminated by a Unix signal (e.g., SIGKILL, SIGTERM), $?.exitstatus returns nil. This caused downstream code to break when comparing exit statuses. Following Unix shell convention, signal terminations now return 128 + signal_number (e.g., 137 for SIGKILL, 143 for SIGTERM). Falls back to exit status 1 if neither exitstatus nor termsig is available.
1 parent 40bc383 commit edcd803

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

lib/parallel_tests/test/runner.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,16 @@ def execute_command_and_capture_output(env, cmd, options)
110110
capture_output(io, env, options)
111111
end
112112
ParallelTests.pids.delete(pid) if pid
113-
exitstatus = $?.exitstatus
113+
114+
status = $?
115+
exitstatus = if status.exitstatus
116+
status.exitstatus
117+
elsif status.termsig
118+
status.termsig + 128
119+
else
120+
1
121+
end
122+
114123
seed = output[/seed (\d+)/, 1]
115124

116125
output = "#{Shellwords.shelljoin(cmd)}\n#{output}" if report_process_command?(options) && options[:serialize_stdout]

spec/parallel_tests/test/runner_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,13 @@ def run_with_file(content)
564564
end
565565
end
566566

567+
it "returns exit status 128 + signal number when terminated by signal", unless: Gem.win_platform? do
568+
run_with_file("Process.kill('KILL', Process.pid)") do |path|
569+
result = call(["ruby", path], 1, 4, {})
570+
expect(result[:exit_status]).to eq 128 + 9 # SIGKILL = 9
571+
end
572+
end
573+
567574
it "prints each stream to the correct stream" do
568575
skip "open3"
569576
_out, err = run_with_file("puts 123 ; $stderr.puts 345 ; exit 5") do |path|

0 commit comments

Comments
 (0)