diff --git a/test/irb/test_debug_cmd.rb b/test/irb/test_debug_cmd.rb index 0242baa26..3ba874230 100644 --- a/test/irb/test_debug_cmd.rb +++ b/test/irb/test_debug_cmd.rb @@ -198,6 +198,8 @@ def test_catch private + TIMEOUT_SEC = 3 + def run_ruby_file(&block) cmd = [EnvUtil.rubybin, "-I", LIB, @ruby_file.to_path] tmp_dir = Dir.mktmpdir @@ -211,7 +213,7 @@ def run_ruby_file(&block) yield PTY.spawn(IRB_AND_DEBUGGER_OPTIONS.merge("IRBRC" => rc_file.to_path), *cmd) do |read, write, pid| - Timeout.timeout(3) do + Timeout.timeout(TIMEOUT_SEC) do while line = safe_gets(read) lines << line @@ -226,6 +228,7 @@ def run_ruby_file(&block) ensure read.close write.close + kill_safely(pid) end lines.join @@ -251,6 +254,35 @@ def safe_gets(read) nil end + def kill_safely pid + return if wait_pid pid, TIMEOUT_SEC + + Process.kill :TERM, pid + return if wait_pid pid, 0.2 + + Process.kill :KILL, pid + Process.waitpid(pid) + rescue Errno::EPERM, Errno::ESRCH + end + + def wait_pid pid, sec + total_sec = 0.0 + wait_sec = 0.001 # 1ms + + while total_sec < sec + if Process.waitpid(pid, Process::WNOHANG) == pid + return true + end + sleep wait_sec + total_sec += wait_sec + wait_sec *= 2 + end + + false + rescue Errno::ECHILD + true + end + def type(command) @commands << command end