-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
8289208: Test DrawRotatedStringUsingRotatedFont.java occasionally crashes on MacOS #9362
Conversation
👋 Welcome back mkartashev! A progress list of the required criteria for merging this PR into |
@mkartashev The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
I must be missing something here, since you say you saw a crash and this fixes it. Principally you seem to be making access to the deferredRecords list thread safe. Second if it is just about MT access to deferredRecords and pulling elements off And if we do somehow have two threads that end up trying to free the same data
So what am I missing ? BTW when we run this test since it is a headless test we would never have accelerated |
Correct. Now let's suppose that the rendering thread - unblocked at the time - is adding more records such that for (int i=0;i<deferredRecords.size(); i++) { loop. The next call to DisposerRecord rec = deferredRecords.get(i); will be executed on the disposer thread simultaneously with the array relocation of
The race was between
I didn't imply that
Are you implying that Be that as it may, |
Don't we have a similar issue in the usage of
Do we need Reference.reachabilityFence at the end of the Note that pollRemove tries to solve that:
But for sure synchronization should solve that in some better way. |
Yes, I believe it can be deallocated before the reference to it is added to
Reference<?> obj = queue.remove();
obj.clear();
DisposerRecord rec = records.remove(obj);
rec.dispose(); Of this I am not so sure. When java.lang.ref.Reference<Object> ref;
...
records.put(ref, rec); |
First, the only way that list grows is here : rq.flushAndInvokeNow(new Runnable() { where Disposer.pollRemove() is adding to the ArrayList deferredRecords This disposeStrike method() is called from the dispose() method in So the ArrayList must have FINISHED "relocating its underlying storage array" BEFORE dispose() returns. So all the following text you have implying concurrent adds / removes etc etc doesn't make sense to me. What I can imagine is that the storage change may not yet be visible to the Disposer thread, So the change to use the ConcurrentLinkedDeque would - if it does what I suppose - fix that. However I don't think you've explained how it leads to the crash. My guess - and the stack trace in the bug perhaps bears this out since it implicates BufImgSurfaceData
And DrawRotatedStringUsingRotatedFont.java does cycle through a lot of BufferedImage instances too ..
It is useless to test this in headless mode since there is no RenderQueue .. and so this whole scenario never happens Both new tests don't seem needed and the 2nd one doesn't seem to be testing the issue at all .. |
(as a side note: many thanks for such an in-depth review).
In the specific macOS case I'm sure that's the right explanation for the crash. But
Let me drop that test and make the existing one headful.
On the issue of the second test, I still believe it is useful:
|
I think it might help us ensure that such a problem will not actually creep in, but I think it |
@mkartashev This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 590 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@prrace, @avu) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
@mkartashev |
You really should wait for the 2nd review before integrating |
@mrserb Are you OK with the current state of the PR? |
maybe @avu can be the 2nd reviewer ? |
Yes, I've looked through the code. It looks good to me. |
/approve |
@avu Unknown command |
/integrate |
@mkartashev |
/sponsor |
Going to push as commit 00decca.
Your commit was automatically rebased without conflicts. |
@avu @mkartashev Pushed as commit 00decca. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This fix appears to be causing test failures in Tier3: JDK-8292304 |
This is the exact new test added by the fix so that shouldn't happen. |
Java2D's
Disposer
maintains a record of objects to dispose of with the help of a collection that isn't thread safe. WhenDisposerRecords
objects are being added to it at the same time as others are being disposed on the Toolkit thread, chaos ensues.This commit replaces the collection with a thread-safe one, more consistently guards against exceptions in individual disposers, and adds exception's stacktraces printing in order to facilitate said exceptions' debugging, which are otherwise hard to pinpoint without code modification.
Originally, the bug was caught on MacOS running an existing test (
DrawRotatedStringUsingRotatedFont
) that would occasionally crash the VM (probably due to double-free detected by libc that abort()'s in this case). It may take many re-tries to reproduce and this wasn't observed on Linux. The new test (test/jdk/sun/java2d/Disposer/TestDisposerRace.java
) displays the problem in a more reliable fashion and fails both on MacOS and Linux without this fix.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/9362/head:pull/9362
$ git checkout pull/9362
Update a local copy of the PR:
$ git checkout pull/9362
$ git pull https://git.openjdk.org/jdk pull/9362/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 9362
View PR using the GUI difftool:
$ git pr show -t 9362
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/9362.diff