Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Background threads can survive ^C #16

Open
treeowl opened this issue Jul 27, 2021 · 2 comments
Open

Background threads can survive ^C #16

treeowl opened this issue Jul 27, 2021 · 2 comments

Comments

@treeowl
Copy link

treeowl commented Jul 27, 2021

I honestly have no idea whether this is a problem in HSpec, hedgehog, or hspec-hedgehog, so I figured I'd start here. I'm running a small test suite testing pure code (so the code being tested doesn't fork anything). Sometimes, the generated test cases are much too large (a bug in my test suite), causing execution to take longer than I want to wait. When I hit ^C, I get back to my shell immediately. Unfortunately, some background thread keeps going in the background, seemingly indefinitely, burning lots of CPU, and I have to kill it separately. Any guesses?

@sol
Copy link
Member

sol commented Nov 1, 2023

I have seen this many times with processes that start a (ghc compiled Haskell) subprocesses. I don't have all the details available right now, but from what I remember, this happens when you try to write to a redirected/captured handle in the subprocess where the reading end has been closed in the parent process.

Something like:

  1. Parent process A starts a subprocess B, creating a pipe hErr for the subprocesse to use as stderr.
  2. On ^C / UserInterupt, A does two things, in that order:
    1. Close hErr
    2. waitForProcess on B
  3. B also receives a UserInterupt (assuming we started it with delegate_ctlc, which I think is the default). The UserInterupt exception is not explicitly handled by B and propagated to the default exception handler.
  4. The default exception handler of B catches the exception and tries to write to stderr.
  5. Writing to stderr fails with some "broken pipe" exception as the reading end hErr has been closed in the parent (GOTO 4).

This results in an infinite loop: 4/5/4/5/4/5/4/5/...

@sol
Copy link
Member

sol commented Nov 1, 2023

I think it's unlikely that this is a bug in hapec or hspec-hedgehog. @treeowl do you remember how you invoked your tests?

If it was through cabal test, or something, then it's probably worth looking at how they start subprocesses.

Specifically, in the parent only close any pipe reading ends after waitForProcess concluded, so that the child process does not go into an infinite loop when trying to write to a "closed" stderr.

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

No branches or pull requests

2 participants