Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/GetThreadListStackTraces/libOneGetThreadListStackTraces.cpp
41155 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2020, NTT DATA.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324#include <jni.h>25#include <jvmti.h>26#include <inttypes.h>27#include <stdio.h>28#include <stdlib.h>2930#define MAX_FRAMES 10031#define ERR_MSG_LEN 10243233#ifdef __cplusplus34extern "C" {35#endif3637static jvmtiEnv *jvmti = NULL;3839JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {40return jvm->GetEnv(reinterpret_cast<void**>(&jvmti), JVMTI_VERSION_11);41}4243static void check_frame_info(JNIEnv *env, jvmtiFrameInfo *fi1, jvmtiFrameInfo *fi2) {44char err_msg[ERR_MSG_LEN] = {0};45if (fi1->method != fi2->method) { /* jvmtiFrameInfo::method */46snprintf(err_msg, sizeof(err_msg),47"method is different: fi1 = %" PRIxPTR ", fi2 = %" PRIxPTR,48(uintptr_t)fi1->method, (uintptr_t)fi2->method);49env->FatalError(err_msg);50} else if (fi1->location != fi2->location) { /* jvmtiFrameInfo::location */51snprintf(err_msg, sizeof(err_msg),52"location is different: fi1 = %" PRId64 ", fi2 = %" PRId64,53(int64_t)fi1->location, (int64_t)fi2->location);54env->FatalError(err_msg);55}56}5758static void check_stack_info(JNIEnv *env, jvmtiStackInfo *si1, jvmtiStackInfo *si2) {59char err_msg[ERR_MSG_LEN] = {0};6061jboolean is_same = env->IsSameObject(si1->thread, si2->thread);62if (env->ExceptionOccurred()) {63env->ExceptionDescribe();64env->FatalError(__FILE__);65}6667if (!is_same) { /* jvmtiStackInfo::thread */68snprintf(err_msg, sizeof(err_msg),69"thread is different: si1 = %" PRIxPTR ", si2 = %" PRIxPTR,70(uintptr_t)si1->thread, (uintptr_t)si2->thread);71env->FatalError(err_msg);72} else if (si1->state != si2->state) { /* jvmtiStackInfo::state */73snprintf(err_msg, sizeof(err_msg),74"state is different: si1 = %d, si2 = %d", si1->state, si2->state);75env->FatalError(err_msg);76} else if (si1->frame_count != si2->frame_count) { /* jvmtiStackInfo::frame_count */77snprintf(err_msg, sizeof(err_msg),78"frame_count is different: si1 = %d, si2 = %d",79si1->frame_count, si2->frame_count);80env->FatalError(err_msg);81} else {82/* Iterate all jvmtiFrameInfo to check */83for (int i = 0; i < si1->frame_count; i++) {84check_frame_info(env, &si1->frame_buffer[i], &si2->frame_buffer[i]);85}86}87}8889JNIEXPORT void JNICALL Java_OneGetThreadListStackTraces_checkCallStacks(JNIEnv *env, jclass cls, jthread thread) {90jvmtiStackInfo *stack_info, *target_info, *target_one_info;91jvmtiError result;92char err_msg[ERR_MSG_LEN] = {0};9394/* Get all stack traces */95jint num_threads;96result = jvmti->GetAllStackTraces(MAX_FRAMES, &stack_info, &num_threads);97if (result != JVMTI_ERROR_NONE) {98snprintf(err_msg, sizeof(err_msg),99"GetAllStackTraces(): result = %d", result);100env->FatalError(err_msg);101}102103/* Find jvmtiStackInfo for `thread` (in arguments) */104jboolean is_same;105target_info = NULL;106for (jint i = 0; i < num_threads; i++) {107is_same = env->IsSameObject(stack_info[i].thread, thread);108if (env->ExceptionOccurred()) {109env->ExceptionDescribe();110env->FatalError(__FILE__);111}112if (is_same) {113target_info = &stack_info[i];114break;115}116}117if (target_info == NULL) {118env->FatalError("Target thread not found");119}120121/*122* Get jvmtiStackInfo via GetThreadListStackTraces().123* It expects to perform in Thread Local Handshake because thread count is 1.124*/125result = jvmti->GetThreadListStackTraces(1, &thread,126MAX_FRAMES, &target_one_info);127if (result != JVMTI_ERROR_NONE) {128snprintf(err_msg, sizeof(err_msg),129"GetThreadListStackTraces(): result = %d", result);130env->FatalError(err_msg);131}132133check_stack_info(env, target_info, target_one_info);134135jvmti->Deallocate(reinterpret_cast<unsigned char *>(stack_info));136jvmti->Deallocate(reinterpret_cast<unsigned char *>(target_one_info));137}138139#ifdef __cplusplus140}141#endif142143144