Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp
40951 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include <stdio.h>24#include <string.h>25#include <jvmti.h>26#include "agent_common.h"2728#include "nsk_tools.h"29#include "JVMTITools.h"30#include "jvmti_tools.h"31#include "jni_tools.h"3233extern "C" {3435#define STATUS_FAILED 236#define PASSED 03738#define METH_NUM 239static const char *METHODS[][2] = {40{ "bpMethod", "()V" },41{ "bpMethod2", "()I" }42};4344static const char *CLASS_SIG =45"Lnsk/jvmti/Breakpoint/breakpoint001;";4647static const char *THREAD_NAME = "breakpoint001Thr";4849static volatile int bpEvents[METH_NUM];50static volatile jint result = PASSED;51static jvmtiEnv *jvmti = NULL;52static jvmtiEventCallbacks callbacks;5354static volatile int callbacksEnabled = NSK_TRUE;55static jrawMonitorID agent_lock;5657static void initCounters() {58int i;5960for (i=0; i<METH_NUM; i++)61bpEvents[i] = 0;62}6364static void setBP(jvmtiEnv *jvmti_env, JNIEnv *env, jclass klass) {65jmethodID mid;66int i;6768for (i=0; i<METH_NUM; i++) {69if (!NSK_JNI_VERIFY(env, (mid = env->GetMethodID(klass, METHODS[i][0], METHODS[i][1])) != NULL))70env->FatalError("failed to get ID for the java method\n");7172if (!NSK_JVMTI_VERIFY(jvmti_env->SetBreakpoint(mid, 0)))73env->FatalError("failed to set breakpoint\n");74}75}7677/** callback functions **/78void JNICALL79ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {80char *sig, *generic;8182jvmti->RawMonitorEnter(agent_lock);8384if (callbacksEnabled) {85// GetClassSignature may be called only during the start or the live phase86if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))87env->FatalError("failed to obtain a class signature\n");8889if (sig != NULL && (strcmp(sig, CLASS_SIG) == 0)) {90NSK_DISPLAY1(91"ClassLoad event received for the class \"%s\"\n"92"\tsetting breakpoints ...\n",93sig);94setBP(jvmti_env, env, klass);95}96}9798jvmti->RawMonitorExit(agent_lock);99}100101void JNICALL102Breakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,103jmethodID method, jlocation location) {104jclass klass;105char *clsSig, *generic, *methNam, *methSig;106jvmtiThreadInfo thr_info;107int checkStatus = PASSED;108int i;109110NSK_DISPLAY0(">>>> Breakpoint event received\n");111112/* checking thread info */113if (!NSK_JVMTI_VERIFY(jvmti_env->GetThreadInfo(thread, &thr_info))) {114result = STATUS_FAILED;115NSK_COMPLAIN0("TEST FAILED: unable to get thread info during Breakpoint callback\n\n");116return;117}118if (thr_info.name == NULL ||119strcmp(thr_info.name,THREAD_NAME) != 0 ||120thr_info.is_daemon == JNI_TRUE) {121result = checkStatus = STATUS_FAILED;122NSK_COMPLAIN2(123"TEST FAILED: Breakpoint event with unexpected thread info:\n"124"\tname: \"%s\"\ttype: %s thread\n\n",125(thr_info.name == NULL) ? "NULL" : thr_info.name,126(thr_info.is_daemon == JNI_TRUE) ? "deamon" : "user");127}128else129NSK_DISPLAY2("CHECK PASSED: thread name: \"%s\"\ttype: %s thread\n",130thr_info.name, (thr_info.is_daemon == JNI_TRUE) ? "deamon" : "user");131132/* checking location */133if (location != 0) {134result = checkStatus = STATUS_FAILED;135NSK_COMPLAIN1("TEST FAILED: Breakpoint event with unexpected location %ld:\n\n",136(long) location);137}138else139NSK_DISPLAY1("CHECK PASSED: location: %ld as expected\n",140(long) location);141142/* checking method info */143if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass))) {144result = checkStatus = STATUS_FAILED;145NSK_COMPLAIN0("TEST FAILED: unable to get method declaring class during Breakpoint callback\n\n");146return;147}148if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &clsSig, &generic))) {149result = checkStatus = STATUS_FAILED;150NSK_COMPLAIN0("TEST FAILED: unable to obtain a class signature during Breakpoint callback\n\n");151return;152}153if (clsSig == NULL ||154strcmp(clsSig,CLASS_SIG) != 0) {155result = checkStatus = STATUS_FAILED;156NSK_COMPLAIN1(157"TEST FAILED: Breakpoint event with unexpected class signature:\n"158"\t\"%s\"\n\n",159(clsSig == NULL) ? "NULL" : clsSig);160}161else162NSK_DISPLAY1("CHECK PASSED: class signature: \"%s\"\n",163clsSig);164165if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodName(method, &methNam, &methSig, NULL))) {166result = checkStatus = STATUS_FAILED;167NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");168return;169}170171for (i=0; i<METH_NUM; i++)172if (strcmp(methNam, METHODS[i][0]) == 0 &&173strcmp(methSig, METHODS[i][1]) == 0) {174NSK_DISPLAY2("CHECK PASSED: method name: \"%s\"\tsignature: \"%s\"\n",175methNam, methSig);176if (checkStatus == PASSED)177bpEvents[i]++;178break;179}180181if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methNam))) {182result = STATUS_FAILED;183NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");184}185if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methSig))) {186result = STATUS_FAILED;187NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method signature\n\n");188}189190NSK_DISPLAY0("<<<<\n\n");191}192193194void JNICALL195VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {196jvmti->RawMonitorEnter(agent_lock);197198callbacksEnabled = NSK_TRUE;199200jvmti->RawMonitorExit(agent_lock);201}202203204void JNICALL205VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {206jvmti->RawMonitorEnter(agent_lock);207208callbacksEnabled = NSK_FALSE;209210jvmti->RawMonitorExit(agent_lock);211}212/************************/213214JNIEXPORT jint JNICALL215Java_nsk_jvmti_Breakpoint_breakpoint001_check(216JNIEnv *env, jobject obj) {217int i;218219for (i=0; i<METH_NUM; i++) {220if (bpEvents[i] != 1) {221result = STATUS_FAILED;222NSK_COMPLAIN3(223"TEST FAILED: wrong number of Breakpoint events\n"224"\tfor the method \"%s %s\":\n"225"\t\tgot: %d\texpected: 1\n",226METHODS[i][0], METHODS[i][1], bpEvents[i]);227}228else229NSK_DISPLAY3("CHECK PASSED: %d Breakpoint event(s) for the method \"%s %s\" as expected\n",230bpEvents[i], METHODS[i][0], METHODS[i][1]);231}232233return result;234}235236#ifdef STATIC_BUILD237JNIEXPORT jint JNICALL Agent_OnLoad_breakpoint001(JavaVM *jvm, char *options, void *reserved) {238return Agent_Initialize(jvm, options, reserved);239}240JNIEXPORT jint JNICALL Agent_OnAttach_breakpoint001(JavaVM *jvm, char *options, void *reserved) {241return Agent_Initialize(jvm, options, reserved);242}243JNIEXPORT jint JNI_OnLoad_breakpoint001(JavaVM *jvm, char *options, void *reserved) {244return JNI_VERSION_1_8;245}246#endif247jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {248jvmtiCapabilities caps;249250/* init framework and parse options */251if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))252return JNI_ERR;253254/* create JVMTI environment */255if (!NSK_VERIFY((jvmti =256nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))257return JNI_ERR;258259initCounters();260261/* add capability to generate compiled method events */262memset(&caps, 0, sizeof(jvmtiCapabilities));263caps.can_generate_breakpoint_events = 1;264if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps)))265return JNI_ERR;266267if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps)))268return JNI_ERR;269270if (!caps.can_generate_single_step_events)271NSK_DISPLAY0("Warning: generation of single step events is not implemented\n");272273/* set event callback */274NSK_DISPLAY0("setting event callbacks ...\n");275(void) memset(&callbacks, 0, sizeof(callbacks));276callbacks.ClassLoad = &ClassLoad;277callbacks.Breakpoint = &Breakpoint;278callbacks.VMStart = &VMStart;279callbacks.VMDeath = &VMDeath;280281if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))282return JNI_ERR;283284NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n");285286if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))287return JNI_ERR;288if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))289return JNI_ERR;290if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))291return JNI_ERR;292if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))293return JNI_ERR;294NSK_DISPLAY0("enabling the events done\n\n");295296if (jvmti->CreateRawMonitor("agent_lock", &agent_lock) != JVMTI_ERROR_NONE) {297return JNI_ERR;298}299300return JNI_OK;301}302303}304305306