8346460: NotifyFramePop should return JVMTI_ERROR_DUPLICATE

Reviewed-by: cjplummer, amenkov
This commit is contained in:
Serguei Spitsyn 2025-01-09 12:02:25 +00:00
parent ceae2b977d
commit 2801bc6bf3
3 changed files with 24 additions and 11 deletions

View File

@ -3084,6 +3084,9 @@ err = (*jvmti)->Deallocate(jvmti, stack_info);
<error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
Thread was not suspended and was not the current thread.
</error>
<error id="JVMTI_ERROR_DUPLICATE">
There is already a frame pop event request at the specified depth.
</error>
</errors>
</function>

View File

@ -1359,7 +1359,11 @@ JvmtiEnvBase::set_frame_pop(JvmtiThreadState* state, javaVFrame* jvf, jint depth
}
assert(jvf->frame_pointer() != nullptr, "frame pointer mustn't be null");
int frame_number = (int)get_frame_count(jvf);
state->env_thread_state((JvmtiEnvBase*)this)->set_frame_pop(frame_number);
JvmtiEnvThreadState* ets = state->env_thread_state(this);
if (ets->is_frame_pop(frame_number)) {
return JVMTI_ERROR_DUPLICATE;
}
ets->set_frame_pop(frame_number);
return JVMTI_ERROR_NONE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -452,13 +452,25 @@ VirtualThreadMount(jvmtiEnv *jvmti, ...) {
mname = get_method_name(jvmti, jni, method);
cname = get_method_class_name(jvmti, jni, method);
print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", ++vthread_mounted_count);
LOG("\nHit #%d: VirtualThreadMount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n",
brkptBreakpointHit, ++vthread_mounted_count, cname, mname, (void*)thread);
brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread);
err = jvmti->NotifyFramePop(thread, 0);
check_jvmti_status(jni, err, "VirtualThreadMount: error in JVMTI NotifyFramePop");
print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", vthread_mounted_count);
LOG("\nHit #%d: VirtualThreadMount #%d: enabling duplicated FramePop for method: %s::%s on virtual thread: %p\n",
brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread);
err = jvmti->NotifyFramePop(thread, 0);
if (err == JVMTI_ERROR_DUPLICATE) {
LOG("NotifyFramePop at VirtualThreadUnmount event returned expected JVMTI_ERROR_DUPLICATE\n");
} else {
LOG("Failed: NotifyFramePop at VirtualThreadUnmount returned %s(%d) instead of expected JVMTI_ERROR_DUPLICATE\n",
TranslateError(err), err);
jni->FatalError("NotifyFramePop error: expected error code JVMTI_ERROR_DUPLICATE");
}
// Test SetThreadLocalStorage for virtual thread.
err = jvmti->SetThreadLocalStorage(thread, tls_data2);
@ -497,13 +509,7 @@ VirtualThreadUnmount(jvmtiEnv *jvmti, ...) {
mname = get_method_name(jvmti, jni, method);
cname = get_method_class_name(jvmti, jni, method);
LOG("\nHit #%d: VirtualThreadUnmount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n",
brkptBreakpointHit, ++vthread_unmounted_count, cname, mname, (void*)thread);
err = jvmti->NotifyFramePop(thread, 0);
check_jvmti_status(jni, err, "VirtualThreadUnmount: error in JVMTI NotifyFramePop");
print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", vthread_unmounted_count);
print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", ++vthread_unmounted_count);
deallocate(jvmti, jni, (void*)mname);
deallocate(jvmti, jni, (void*)cname);