-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
8243455: Many SA tests can fail due to trying to get the stack trace of an active method #2700
Conversation
👋 Welcome back cjplummer! A progress list of the required criteria for merging this PR into |
@plummercj The following labels 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 lists. If you would like to change these labels, use the /label pull request command. |
/label remove core-libs |
@plummercj |
Webrevs
|
Mailing list message from David Holmes on serviceability-dev: Hi Chris, On 4/03/2021 6:09 am, Chris Plummer wrote:
Doesn't jstack force all threads to be walkable via a safepoint or David |
Nope. If it did it couldn't debug core files or a hung process. That's why SA has so much code to safe guard against walking off the deep end when doing things like stack walking and heap scanning. BTW, you might be thinking of the Attach API version of |
Ping! I could use one more reviewer. Thanks! |
// Do another short sleep so we can get into the synchronized block, | ||
// although this probably is not necessary to guarantee that the | ||
// stack trace is readable. | ||
Thread.sleep(100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we wait to change the state of steadyStateThread
to BLOCKED
? It is more robustness than Thread.sleep(100)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, can we write following code?
while (steadyStateThread.getState() != Thread.State.BLOCKED) {
Thread.onSpinWait();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's easy enough. What about the loop before it. Do you prefer 100ms sleeps or onSpinWait() for it also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer onSpinWait()
if anything because it expects short suspend, and we can expect CPU friendly code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an option, we can remove steadyStateReached
and rewrite the code as following:
steadyStateThread.setName("SteadyStateThread");
steadyStateThread.start();
while (steadyStateThread.getState() != Thread.State.BLOCKED) {
Thread.onSpinWait();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought of that, but was worried that during thread startup maybe there might be a spurious short lived period where the thread was BLOCKED. Probably not possible, but I didn't want to have to go about proving as much.
@plummercj 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 213 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. ➡️ To integrate this PR with the above commit message to the |
Chris, test/lib/jdk/test/lib/apps/LingeredApp.java It is better to rename
It is better to remove the second sleep as it is not really needed. Another concern is that the stack trace of this thread is going to be trivial, not sure if it is useful. -Serguei |
I'll fix that.
You were looking at the first version. It was updated last night.
It's no less trivial than the main thread that tests used to look for, except that previously once in a great while the thread woke up from sleep (and that usually resulted in a test failure because the stack trace could not be produced). However, I also have a PR 2720 to add a stack trace stress test. |
/integrate |
@plummercj Since your change was applied there have been 260 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 43524cc. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Many tests run
LingeredApp
, get its stack withjstack
, and then look forLingeredApp.main
in the output, which should appear in the stack trace of the main thread. Usually this works fine since the main thread is in a loop, and usually blocked inThread.sleep()
. However, during the short period of time it wakes up from sleep, the thread's stack might not be walk-able, in which case theLingeredApp.main
frame will not appear, and the tests looking for it will fail.The fix is to introduce a new thread called
SteadyStateThread
that has a method calledsteadyState()
that blocks indefinitely trying to synchronize on a locked object. All code that used to look forLingeredApp.main
in the output now instead looks forLingeredApp.steadyState
, which should always be there. I'm open to suggestions for a better name than "SteadyState" if you have one.There are a few special cases with the tests that were modified that are described below:
Regarding the removal of
LingeredAppWithTrivialMain.java
, it was originally added to fix JDK-8229118, which was an issue with theClhsdbFindPC
test failing on aarch64 when doing the-Xcomp
run. It expectedLingeredApp.main()
to be compiled in that case, and for the PC of the frame to be in anNMethod
. However, on aarch64 an uncommon-trap was causing it to be de-optimized, so the PC was in the interpreter instead, causing the test to fail. The fix was to instead rely on finding a trivialLingeredAppWithTrivialMain.main()
frame in the stack trace since it would always be compiled. With the changes to instead have (and rely on) theSteadyStateThread
and the presence ofLingeredApp.steadyState()
, the need forLingeredAppWithTrivialMain
goes away.LingeredApp.steadyState()
will always be compiled, even on aarch64.Regarding
DebugdConnectTest.java
, it is listed in the CR as an affected test but no specified fix has been provided.None is needed. The issue was that it looked for
LingeredApp
in the jstack output, and it used to be the only place it would find it was in the main thread's stack trace, which sometimes could not be retrieved. Now it can also be found in theSteadyStateThread
's stack trace, which can always be retrieved.Regarding
HeapDumpTest.java
, it used to check forLingeredAppWithExtendedChars.main
and now it checks forLingeredApp.steadyState
. It still is run withLingeredAppWithExtendedChars
. The only thing special about that class is that it contains an extended unicode character used to reproduce JDK-8028623, so it will still do that, even though it now checks forLingeredApp.steadyState
.Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/2700/head:pull/2700
$ git checkout pull/2700