Skip to content

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

Open

Description

@joker1007

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 #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.

Activity

  1. ko1 commented on Aug 14, 2025

    @ko1
    Collaborator

    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
    
  2. joker1007 commented on Aug 15, 2025

    @joker1007
    Author

    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. 😅 )

  3. ko1 commented on Dec 5, 2025

    @ko1
    Collaborator

    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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions