-
Notifications
You must be signed in to change notification settings - Fork 10.9k
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
Possible deadlock in ImmutableList #1977
Comments
Can you elaborate on the deadlock? I guess the idea is that one thread starts to load ImmutableList while the other starts to load RegularImmutableList? That's probably not good, though we may have this problem in a lot of places, and I haven't heard reports of trouble... yet... |
Here is the minimal test case I could create. It hangs intermittently.
The problem is not just theoretical - we've hit the real deadlock in a large production deployment. |
Sorry, I missed the last part of your message (about how you've hit this in prod). That makes more much more worried about this. Part of the reason I'm worried is that we might have these cycles in lots of places. I'll fix this one, but we may have others. Maybe we should write a test that loads each of our classes in a new, instrumented |
(The specific problem of |
This was requested in #1977 to avoid circular static-init dependencies. I fear that we have other such problems. We should consider adding a test for them. ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=88131198
Thought about this a little more today. One subtlety here is how the app starts to initialize Until then, I had hoped that I could restrict my search to classes that involve But if I turn off the restriction, again, I get many results, most of which are false positives. But to actually determine which are true positives, I'd have to soup up the analyzer. I think I need to find cases where we can get from a Given that, I think I'll just go after the high-visibility classes with potential problems: |
- ImmutableSortedMultiset: I couldn't figure out a way for this to actually deadlock, but I figure it's best for it to follow the pattern of the others. - ImmutableSortedSet: This might be able to deadlock if one thread creates a RegularImmutableMap (which then calls into RegularImmutableSortedSet and then ImmutableSet) while another initializes ImmutableSortedSet (which then calls into RegularImmutableSortedSet). - ImmutableTable: This might be able to deadlock if one thread GWT-deserializes a SparseImmutableTable (which then calls into ImmutableTable) while another initializes ImmutableTable (which calls into SparseImmutableTable). ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=104995935
To detect any remaining or new problems, we could look at ArchUnit for its Cycle Checks (mentioned in #4011 (comment)). [edit: Oops, sorry, I think ArchUnit is talking about a different kind of cycle, so it's unlikely to help here.] |
I've requested ArchUnit sample via TNG/ArchUnit#470 |
@cpovirk I've built an errorprone check which detects precisely this kind of deadlock here: palantir/gradle-baseline#1598 I'd be more than happy to transfer the code upstream into error-prone if there's interest. |
Thanks! I am interested in principle. My fear has been that such a checker may be prone to false positives, but if they turn out to be easy enough to work around, we'd probably enable a check anyway as a precaution. |
I've added an error-prone ticket to discuss upstreaming the check: google/error-prone#2062 |
ImmutableList contains following code since version 15.0
private static final ImmutableList EMPTY =
new RegularImmutableList(ObjectArrays.EMPTY_ARRAY);
The text was updated successfully, but these errors were encountered: