-
Notifications
You must be signed in to change notification settings - Fork 313
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
OrderedSet.intersection crashes due to out of bounds index #104
Comments
@simme Thanks for the report! If I understand correctly, one of your sets ( The two leading candidates for explaining an off-by-one error like this are (1) a race condition where two threads are mutating the hash table at once, and they clobber each other's updates, or (2) a logic error in OrderedSet where a mutating method fails to correctly renumber hash table contents. It's difficult to tell from the report which of these two candidates is the real cause (if either). To help narrow this down, could you tell a little more about your code?
If this turns out to be a data race, then running your app with ASan enabled will probably pinpoint the issue. Otherwise defining the |
(0.0.7 has the same OrderedSet implementation as main -- there is no reason to spend effort on reproducing this there.) |
Removing the 1.0 milestone. A quick audit uncovered no obvious issues within the package. If this turns out to be a package issue, then the fix can ship in a patch release as soon as we track it down! #106 will provide more debugging options by marking |
Thanks for taking a look!
Ran the app with Adress Sanitizer turned on (and "Detect use of stack after return"). Never done that before, but didn't see any warnings in the console or in Xcode. Tried running with the build conditions. Not sure if I did it right though. Sorry if this is not of much help. Let me know if there's anything else I can do to attempt to pin-point the issue. I understand it's very likely that the cause is something I'm doing or any of the layers between me and the corrupted set. |
This is good information, thanks! The build settings look good to me! The issue could be nondeterministic, so it's possible it will only occur in a small fraction of runs. (Disabling deterministic hashing may help reproduce it more often, especially if you are using the same data across runs -- it could well be that the hashes just happen to align well with the deterministic seed. That said, the number of possible storage permutations in a 1.3k set is immense, and it's technically possible that the pattern that triggers the logic error (if it's that) may never happen again.) |
Ok, good that it was to some use! :) The crash happens 100% of the time with my data. So in that sense it is deterministic. |
I'll see if I can find some time to setup a reproduction case with my actual data. Kinda in crunch mode for a 1.0 release right now, so a little tied up though. |
Huh; that makes it extremely likely this is a logic error in the package. If there's any way you can extract a reliable reproducer, then that would likely immediately show me the fix! Meanwhile, I'll investigate more. |
#107 fixes a bug that was uncovered while trying to reproduce this. I don't think it's the same issue (this isn't the right code path and I don't see how it could trigger crashes of this sort) -- but it may be worth trying nevertheless. (If you use an xcworkspace in your app project, one relatively easy way to test unreleased package changes is to clone #107 to a local repo and to add its folder to the workspace -- Xcode will pick up the local repo instead of using the regular dependency resolution algorithm.) |
I have not forgotten about this. Just a little tied up at the moment, as I mentioned. The instance of Collections that I'm using is a dependency, to a dependency, to a dependency at the moment. If I add my own dependency on Collections in my |
That's perfectly understandable! I haven't seen other reports of this issue, so I'm treating it as a worrying problem that could escalate into something serious, rather than as an active emergency. (Given that you can readily reproduce this, running the 1.0.0 tag with COLLECTIONS_INTERNAL_CHECKS enabled might be enough to pinpoint the operation that triggers the corruption. (v1.0 includes some improvements to internal checking.))
With Xcode's package support, the most straightforward way I know of overriding the regular dependency resolution process is to add a local clone of the package directly to the workspace (like |
I have been trying to reproduce this in a smaller sample project to no avail. It is still 100% reproducible in my main project, even using version 1.0.1 of Collections. I'd be willing to send you the code for my entire app through some private means and walk you through how to trigger the issue if you think that'd help! |
Hi folks, I’ve been seeing a similar issue via the IdentifiedArray type that wraps an Poking around in the stacktrace a bit and it seems like at some point I’m trying to make a small reproducible test case, which is made a bit difficult by the fact that pretty much the same code does not crash in another code path; i’m adding the reply to the list after it’s accepted by the server. When I relaunch the app and attempt to sync again, it sends back an array with the same exact value, and this time the code does not crash, which has me a bit befuddled. Adding a fresh reply after this initial merge however does cause the same crash, and so I’m not really sure what’s happening here. I realise this probably isn’t very helpful without a reproducible sample but until I can have that, please do let me know if I can help in any other way. |
@simme I'd be glad to help debug this -- you can DM me on the forums or Twitter to set things up. @HarshilShah That sounds like hash seed randomization is making the issue nondeterministic, which is very much expected, if this is an issue with the hash table implementation. Setting SWIFT_DETERMINISTIC_HASHING=1 would likely help with the reduction effort! |
Ah nice, I’ll try to enable that flag and see what happens! |
In a small learning project I can reproduce this or a similar crash in a 100% reliable manner. I cloned the swift-collections repo and added it all into a xcworkspace as recommended by @lorentey. Calling
After the insert there's 30 items. However in the view update the inserted item is not present anymore. There's only 29 items. |
This turned out to be caused by a missing uniqueness check in a couple of Embarrassingly, this wasn't caught by the existing tests that check value semantics, because they only checked that iteration over old snapshots still provided consistent results, not that those snapshots were fully self-consistent. D'oh! The fix is #123; this will ship in a new release very soon. Big shoutout to @KaiOelfke for providing me with a reproducer! |
That's great! Once the path is live I'll verify in my app that the issue has been fixed. Sorry for dropping the ball on this. |
It looks like the PR link did not trigger -- manually marking this as resolved. 1.0.2 will be released later today; please verify & reopen if this still triggers there. |
If have two
OrderedSet
s of what are essentially UUIDs (wrapped in Tagged). Finding theintersection
fromsetA
works.But taking the two, same, sets and flipping the order causes an out of bounds crash in RandomAccessCollection+Offsets.swift#28.
The items in the sets are 1389 vs. 1388 if that could somehow matter.
Here's a stack trace if it helps:
Information
Checklist
main
branch of this package.Did not attempt to reproduce on
main
asswift-collections
is a sub-dependency on one of my dependencies. But could absolutely try if requested. Getting late where I am 😅Steps to Reproduce
I have not been able to reproduce this issue unfortunately. I'm doing this a on a few different pairs of sets, and only one of them with this specific type (
Tagged<Product, UUID>
— product being a customstruct
) causes the issue. The other sets are alsoTagged<X, UUID>
.Happy to attempt to provide more attempts to reproduce. The inner workings of all this is a bit over my head though.
Expected behavior
I expect the "call order" to not matter.
Actual behavior
Out of bounds crash.
The text was updated successfully, but these errors were encountered: