-
Notifications
You must be signed in to change notification settings - Fork 108
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
Strange behaviour when a test causes a <<loop>> #238
Comments
Reminds me of #15 (comment), and I suspect the cause (or even the fix) to be similar. Would be also nice to add a test for this once we figure it out. |
I think I don't understand even the basics of what could be going on. Why is it possible for the calling context to affect the behaviour of the loop detector? I can sort of see in #15 that the actual result being passed across threads was the loop itself so the non-termination was being exported, but in my example I'm being very careful to force it to become an exception inside the test itself. |
I'm not so sure about that. You are not generating an exception inside the test; you're relying on the RTS/GC to supply it. And the GC analyses the heap as a whole, so the global state of the heap affects the outcome. Here's a minimal example that doesn't even involve any concurrency: import Control.Exception
import Foreign.StablePtr
loopy =
catch
(evaluate (let x = x in x))
(print :: SomeException -> IO())
main = do
newStablePtr loopy
loopy The example above just hangs here (8.6.3, Linux x86-64, non-threaded RTS), whereas if you comment the newStablePtr line, it prints the exception. The reason (I think) is because the reference to the blackholed thunk is retained independently, and the GC realizes that there's an opportunity that the thunk will be eventually updated. I suspect that something similar is happening within tasty (the test references the thunk, the main thread references the test tree etc., plus the fact that we have a stable ptr to the main thread as discussed in #15). |
When the RTS detects a loop in a test case, I'm seeing strange behaviour from tasty. Consider the following code, which has a loop that can easily be detected:
On Windows (GHC 8.2.2) instead of seeing a
NonTermination
exception, I getAsyncCancelled
getting caught directly, and then somehow the
NonTermination
leaks past it and takes down thewhole program:
On LInux (GHC 8.2.2 and GHC 8.4.3), the test just hangs, not using CPU:
In each case I'm using tasty 1.2.1 and tasty-hunit 0.10.0.1.
If I change the loop to some other exception, e.g. by commenting out the
evaluate
line and uncommenting thefail
line in the above code, then it's caught as expected and the test infrastructure continues normally:I guess it must be something to do with the way tasty runs tests with STM on separate threads. Is there some obvious reason for this I'm missing or is it known already? If not I can try to understand the behaviour better by inlining the tasty test runner code into my example program.
The text was updated successfully, but these errors were encountered: