debug icon indicating copy to clipboard operation
debug copied to clipboard

at_exit hook sometimes freeze forever when a rails application executes test codes

Open joker1007 opened this issue 4 months ago • 3 comments

Your environment

  • ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux]
  • rdbg 1.11.0

Describe the bug

This issue is related to https://github.com/ruby/debug/issues/1113.

Since the at_exit hook waits for all child processes other than the Ruby process, it leads to the following problem in the test code of a real Rails application.

  1. Load the debug gem
  2. The capybara-playwright-driver starts Playwright as a child process
  3. The capybara-playwright-driver registers an at_exit hook to terminate Playwright when the test ends
  4. During test code execution, when a fork occurs, the debug gem registers the at_exit hook
  5. After all test cases have finished, the debug gem's at_exit hook executes first and waits for the child process to terminate, but since the at_exit hook to terminate Playwright does not execute, it continues to wait indefinitely

This can occur normally if the debug gem is required. If it happens in a CI execution environment, it could result in unnecessary costs by holding computing resources for a long time.

I believe that waiting for all child processes(including not Ruby process) after a fork occurs is a significant issue.

To Reproduce

I described above.

Expected behavior

process finishes successfully.

joker1007 avatar Aug 14 '25 16:08 joker1007

Could you make a repro-scenario with simple script without capybara and so on?

My understanding is correct?

test
  -> call capybara-playwright-driver
    -> fork Playwright (*)

at the end of the test, wait for termination of (*) and it doesn't terminate, wait forever

ko1 avatar Aug 14 '25 17:08 ko1

It's not exactly correct. I mean the situation like below.

test
  -> run browser test (launch playwright with popen3)
    -> run other tests
      -> fork in a test code or a production code for parallelism

at the end of the test, wait for termination of (*) and it doesn't terminate, wait forever

Normally, the order in which tests are executed is random, and it is difficult to write tests for Rails applications without using Capybara. I think the reason why problems rarely occur is that there are not many situations where forks are used in Rails applications or test code. But if an application that uses forks requires the debug gem, I think it would be difficult to understand the problem without being very familiar with the debug gem. (That's what happened to me. 😅 )

joker1007 avatar Aug 15 '25 03:08 joker1007

Sorry for late response.

Maybe the combination with fork and debug.gem should be reconsidered again. Currently, waiting for all child process because of TTY.

  1. User runs a process A, with debugger, on a terminal
  2. A forks process B
  3. A terminated before B, but B has debugger context
  4. The user regains control of the terminal
  5. B stops at breakpoint and mixing the shell and debugger prompt -> 🔥

I want to hear how to handle that...

ko1 avatar Dec 05 '25 09:12 ko1