Skip to content

Commit

Permalink
[JDK19+] Fix JVMTI GetAllStackTraces
Browse files Browse the repository at this point in the history
JVMTI GetAllStackTraces only tracks live platform threads.

This change correctly and consistently derives the threadObject
from J9VMThread->carrierThreadObject in GetAllStackTraces for JDK19+.

Currently, J9VMThread->threadObject is used in some places, which is
incorrect since it can also point to a virtual thread.

Related: eclipse-openj9#17868

Signed-off-by: Babneet Singh <[email protected]>
  • Loading branch information
babsingh committed Aug 3, 2023
1 parent a40721e commit 1359006
Showing 1 changed file with 24 additions and 23 deletions.
47 changes: 24 additions & 23 deletions runtime/jvmti/jvmtiStackFrame.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,18 @@ jvmtiGetAllStackTraces(jvmtiEnv* env,
jvmtiStackInfo** stack_info_ptr,
jint* thread_count_ptr)
{
J9JavaVM * vm = JAVAVM_FROM_ENV(env);
jvmtiError rc;
J9VMThread * currentThread;
J9JavaVM *vm = JAVAVM_FROM_ENV(env);
PORT_ACCESS_FROM_JAVAVM(vm);

jvmtiError rc = JVMTI_ERROR_NONE;
J9VMThread *currentThread = NULL;
jvmtiStackInfo *rv_stack_info = NULL;
jint rv_thread_count = 0;

Trc_JVMTI_jvmtiGetAllStackTraces_Entry(env);

rc = getCurrentVMThread(vm, &currentThread);
if (rc == JVMTI_ERROR_NONE) {
if (JVMTI_ERROR_NONE == rc) {
UDATA threadCount;
jvmtiStackInfo * stackInfo;

Expand All @@ -122,40 +123,40 @@ jvmtiGetAllStackTraces(jvmtiEnv* env,

threadCount = vm->totalThreadCount;
stackInfo = j9mem_allocate_memory(((sizeof(jvmtiStackInfo) + (max_frame_count * sizeof(jvmtiFrameInfo))) * threadCount) + sizeof(jlocation), J9MEM_CATEGORY_JVMTI_ALLOCATE);
if (stackInfo == NULL) {
if (NULL == stackInfo) {
rc = JVMTI_ERROR_OUT_OF_MEMORY;
} else {
jvmtiFrameInfo * currentFrameInfo = (jvmtiFrameInfo *) ((((UDATA) (stackInfo + threadCount)) + sizeof(jlocation)) & ~sizeof(jlocation));
jvmtiStackInfo * currentStackInfo = stackInfo;
J9VMThread * targetThread;
jvmtiFrameInfo *currentFrameInfo = (jvmtiFrameInfo *)((((UDATA)(stackInfo + threadCount)) + sizeof(jlocation)) & ~sizeof(jlocation));
jvmtiStackInfo *currentStackInfo = stackInfo;
J9VMThread *targetThread = vm->mainThread;

targetThread = vm->mainThread;
do {
/* If threadObject is NULL, ignore this thread */

if (targetThread->threadObject == NULL) {
/* If threadObject is NULL, ignore this thread. */
#if JAVA_SPEC_VERSION >= 19
j9object_t threadObject = targetThread->carrierThreadObject;
#else /* JAVA_SPEC_VERSION >= 19 */
j9object_t threadObject = targetThread->threadObject;
#endif /* JAVA_SPEC_VERSION >= 19 */
if (NULL == threadObject) {
--threadCount;
} else {
rc = jvmtiInternalGetStackTrace(
env,
currentThread,
targetThread,
#if JAVA_SPEC_VERSION >= 19
targetThread->carrierThreadObject,
#else /* JAVA_SPEC_VERSION >= 19 */
targetThread->threadObject,
#endif /* JAVA_SPEC_VERSION >= 19 */
threadObject,
0,
(UDATA) max_frame_count,
(void *) currentFrameInfo,
(UDATA)max_frame_count,
(void *)currentFrameInfo,
&(currentStackInfo->frame_count));
if (rc != JVMTI_ERROR_NONE) {

if (JVMTI_ERROR_NONE != rc) {
j9mem_free_memory(stackInfo);
goto fail;
}

currentStackInfo->thread = (jthread) vm->internalVMFunctions->j9jni_createLocalRef((JNIEnv *) currentThread, (j9object_t) targetThread->threadObject);
currentStackInfo->state = getThreadState(currentThread, targetThread->threadObject);
currentStackInfo->thread = (jthread)vm->internalVMFunctions->j9jni_createLocalRef((JNIEnv *)currentThread, threadObject);
currentStackInfo->state = getThreadState(currentThread, threadObject);
currentStackInfo->frame_buffer = currentFrameInfo;

++currentStackInfo;
Expand All @@ -164,7 +165,7 @@ jvmtiGetAllStackTraces(jvmtiEnv* env,
} while ((targetThread = targetThread->linkNext) != vm->mainThread);

rv_stack_info = stackInfo;
rv_thread_count = (jint) threadCount;
rv_thread_count = (jint)threadCount;
}
fail:
vm->internalVMFunctions->releaseExclusiveVMAccess(currentThread);
Expand Down

0 comments on commit 1359006

Please sign in to comment.