-
Notifications
You must be signed in to change notification settings - Fork 139
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
Boxed mutable vector is buggy in doctests #385
Comments
This doctest is bad. It calls unsafeFreeze on the same mutable vector twice, which is explicitly undefined behavior. |
@andrewthad You know, I thought exact same thing a moment ago and did just that in 997615a However, this is not described anywhere in a good detail. The only place I saw any mention of this was in I know you are more familiar with the actual primops, so I have few questions for you:
>>> mv <- V.thaw $ V.fromList ([10, 20, 30] :: [Integer])
>>> mv' <- MV.grow mv 2
>>> MV.write mv' 3 999
>>> MV.write mv' 4 777
>>> v' <- V.unsafeFreeze mv'
>>> print v'
[10,20,30,999,777]
>>> mv'' <- V.unsafeThaw v'
>>> MV.write mv'' 2 888
>>> v''' <- V.unsafeFreeze mv''
>>> print v'''
[10,20,888,999,777]
>>> V.unsafeFreeze mv
[10,20,30] |
Here's the reason I'm certain of for why mutating after performing an in-place freeze is bad. For any type of array (
What is the value of
I'll write up some more observations later tonight. |
Right. The floating out part certainly makes sense, but that is not the problem in the original doctest. There is exact sequencing because the value is printed to stdout, thus it can't be floated out. |
Digging through the actual implementation does not reveal the reason to me.
|
|
Oh damn, you are right, I was looking at freezeArray#!!! |
Also, fwiw, I consider You're looking at |
Now that I looked into the right primop it all makes total sense. @andrewthad Thank you for your feedback.
100% agree: #139 (comment) |
Fix for the bug is in #384 |
I still have no idea what's really happening that causes the original problem. Only a hand-wavy "this is undefined behavior, so anything goes". Other random thoughts. You asked:
I don't know. Writing and in-place freezing are both more complicated for boxed arrays than for
By contrast, unboxed arrays just a single closure type used for both
So there's that. And then there's also the issue of GHC, as a memory ordering concern, has to make sure that writes to the memory backing a freshly-allocated boxed value are seen before its pointer gets written to an array. This only matters when multithreading is in play, and historically, this caused problems on ARM, but Ben Gamari fixed all of this in the GHC 8.10.x series. Those are the differences that I'm aware of that might matter. But I don't really know how doctest works, and it might be introducing other problems. |
I like the fix you chose. Using |
So far I can't reproduce bug with either GHC or doctests (I'm using GHC 8.8)
What worry me is 283563033355. What is it? Could it be that GC happening at inopportune moment is able to write some junk to vector? |
I am able to reproduce it with doctests, but very rarely. It is not triggered consistently and outside doctests I've never seen it happened at all and I've written some property tests, tried it ghci while forcing GC at various steps.
I suspect it reads some arbitrary memory location and interprets its contents as One way or another >>> v' <- V.unsafeFreeze mv'
>>> print v'
[10,20,30,999,777]
>>> mv'' <- V.unsafeThaw v'
>>> MV.write mv'' 2 888 because |
Closing this issue with #384 PR |
Since I've added some doctests for
grow
function we've been experiencing some occasional segfaults on CI, but it was hard to spot where exactly the problem is lurking, since examples themselves seem to be correct and problem can't be replicated outside of doctests. I've experienced very similar problem elsewhere with boxedMutableArray#
andSmallMutableArray#
, so I had a hunch (#382 (comment)) that it had to do with boxed arrays and today we got this error on CI:See https://github.com/haskell/vector/runs/2461343762?check_suite_focus=true
I'll inline example from haddock for the record:
It is clear that there is something really weird going on. I am not 100% sure where the problem is really coming from, although I do suspect it probably is
doctests
, but since it originated here I'd like to have it as a starting point.@Shimuuar You've expressed interest in investigating it. Any ideas?
The text was updated successfully, but these errors were encountered: