Skip to content
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

JDK24 serviceability_jvmti_j9_0_FAILED serviceability/jvmti/vthread/CheckHiddenFrames/CheckHiddenFrames.java RuntimeException: CheckHiddenFrames failed! #20541

Open
JasonFengJ9 opened this issue Nov 7, 2024 · 19 comments · May be fixed by #21084

Comments

@JasonFengJ9
Copy link
Member

JasonFengJ9 commented Nov 7, 2024

Failure link

From an internal build(ubu22-aarch64-5):

16:23:10  openjdk version "24-internal" 2025-03-18
16:23:10  OpenJDK Runtime Environment (build 24-internal-adhoc.jenkins.BuildJDKnextaarch64linuxPersonal)
16:23:10  Eclipse OpenJ9 VM (build master-24c86c0ca8b, JRE 24 Linux aarch64-64-Bit Compressed References 20241106_129 (JIT enabled, AOT enabled)
16:23:10  OpenJ9   - 24c86c0ca8b
16:23:10  OMR      - 6fa180614ec
16:23:10  JCL      - 5a723c02858 based on jdk-24+22)

Rerun in Grinder - Change TARGET to run only the failed test targets.

Optional info

Failure output (captured from console output)

16:24:37  ===============================================
16:24:37  Running test serviceability_jvmti_j9_0 ...
16:24:37  ===============================================
16:24:37  serviceability_jvmti_j9_0 Start Time: Wed Nov  6 21:24:36 2024 Epoch Time (ms): 1730928276459
16:24:37  variation: Mode150
16:24:37  JVM_OPTIONS:  -XX:+UseCompressedOops -Xverbosegclog 

16:28:27  TEST: serviceability/jvmti/vthread/CheckHiddenFrames/CheckHiddenFrames.java

16:28:27  Failed: GetStackTrace returned info for frame expected to be hidden: frame[0]=yield0
16:28:27  Failed: GetStackTrace returned info for frame expected to be hidden: frame[1]=yield
16:28:27  STDERR:
16:28:27  java.lang.RuntimeException: CheckHiddenFrames failed!
16:28:27  	at CheckHiddenFrames.main(CheckHiddenFrames.java:47)
16:28:27  	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
16:28:27  	at java.base/java.lang.reflect.Method.invoke(Method.java:573)
16:28:27  	at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
16:28:27  	at java.base/java.lang.Thread.run(Thread.java:1588)
16:28:27  
16:28:27  JavaTest Message: Test threw exception: java.lang.RuntimeException: CheckHiddenFrames failed!

16:29:36  serviceability_jvmti_j9_0_FAILED

50x internal grinder - all failed

Copy link

github-actions bot commented Nov 7, 2024

Issue Number: 20541
Status: Open
Recommended Components: comp:jvmti, comp:vm, comp:test
Recommended Assignees: babsingh, jasonfengj9, llxia

@JasonFengJ9 JasonFengJ9 added this to the Java 24 milestone Nov 7, 2024
@tajila
Copy link
Contributor

tajila commented Jan 21, 2025

@thallium Please take a look at this

@thallium
Copy link
Contributor

I'll look into this.

@thallium
Copy link
Contributor

The author of the test stated that the yield() and yield0() should also have the @JvmtiMountTransition annotation thus will not appear in the JVMTI stacktrace. Do we want to match the behaviour as well?

@tajila
Copy link
Contributor

tajila commented Jan 23, 2025

The author of the test openjdk/jdk#21397 (comment) that the yield() and yield0() should also have the @JvmtiMountTransition annotation thus will not appear in the JVMTI stacktrace. Do we want to match the behaviour as well?

Yes please add that

@thallium
Copy link
Contributor

@babsingh we also need to skip JvmtiMountTransition frames in jvmtiGetFrameLocation(). Can I just use jvmtiInternalGetStackTraceIterator as frame walk function?

@babsingh
Copy link
Contributor

genericFrameIterator skips JvmtiMountTransition frames and is more lightweight than jvmtiInternalGetStackTraceIterator. Can you use genericFrameIterator instead?

@thallium
Copy link
Contributor

Yeah for sure, I didn't notice genericFrameIterator.

@thallium
Copy link
Contributor

Actually we might have to change the stack walker code. The current problem is that decrementing walkState->skipCount and incrementing walkState->framesWalked happens before calling frameWalkFunction therefore walking a JvmtiMountTransition frame will still result in walkState->skipCount and walkState->framesWalked being changes. So I think handling of JvmtiMountTransition frames should be in the stack walker code rather than in frameWalkFunction. Does this sound good to you @gacholio?

@gacholio
Copy link
Contributor

Does this sound good

Definitely not. Can you please point me at the iterator code?

@thallium
Copy link
Contributor

https://github.com/eclipse-openj9/openj9/blob/master/runtime/jvmti/jvmtiHelpers.cpp#L2089 If we don't want to modify stack walker code, I think we will need to call stack walker twice to skip the correct number of frames.

@gacholio
Copy link
Contributor

Can you please summarize the issue as you see it and the 2 walk solution you are proposing?

@thallium
Copy link
Contributor

The issue is that frames with JvmtiMountTransition annotation need to be skipped in JVMTI stacktrace. Currently JVMTI GetFrameLocation(..., jint depth, ...) will not return correct frame if there is any JvmtiMountTransition frame in the stack. This is because the implementation of GetFrameLocation sets walkState.skipCount = depth therefore JvmtiMountTransition frames will be skipped and exhaust walkState.skipCount.

A solution I can think of without modifying stack walker code is to firstly walk the stack with genericFrameIterator to get the number of JvmtiMountTransition frames and add it to walkState.skipCount for the second walk.

@gacholio
Copy link
Contributor

gacholio commented Feb 3, 2025

I haven't looked at this in detail, but above you mention the issue that counts are adjusted before the callback fires. Can you use this knowledge in the callback? If you really know what you're doing, you could adjust the count values in the callback, though this would generally be discouraged.

Niote that skipCount applies only to the top frames on the stack, so I doubt it could be used to skip transition frames that I assume aren't necessarily all on top of stack.

@gacholio
Copy link
Contributor

gacholio commented Feb 4, 2025

I don't understand why it would be difficult to skip the marked frames.

@thallium
Copy link
Contributor

thallium commented Feb 4, 2025

but above you mention the issue that counts are adjusted before the callback fires

This is only part of the problem. The bigger issue is that if walkState.skipCount is specified by user we will get incorrect result. For example, let's say the current stack looks like:

Transition Frame
Frame 1
Frame 2
Frame 3

If the skip count is set to 2, we will get Frame 2 as result but the expected frame is Frame 3. I don't think we can do anything in the callback to account for this because the Transition Frame is simply skipped without calling the callback. So we either have to do a first walk to know the number of transition frames and add it to the skip count of the second walk (assuming transition frames are always on the top of the stack, @babsingh can you confirm?), or handle transition frames in stack walker.

@gacholio
Copy link
Contributor

gacholio commented Feb 4, 2025

Ah, so you think the skipping should only take unmarked frames into account. The callback will not fire for skipped frames, so I begin to see the issue.

@gacholio
Copy link
Contributor

gacholio commented Feb 4, 2025

An obvious solution would be to set skipCount to 0 and manage the frames yourself in the callback.

@gacholio
Copy link
Contributor

gacholio commented Feb 5, 2025

In general, skipCount is used to remove implementation-specific frames from consideration during stack walks (for example, skipping the top frame which is the native implementing whatever is doing the walking).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants