1 /* 2 * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. 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 it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 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 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include <stdlib.h> 25 #include <string.h> 26 #include "jni_tools.h" 27 #include "agent_common.h" 28 #include "jvmti_tools.h" 29 30 #define PASSED 0 31 #define STATUS_FAILED 2 32 33 extern "C" { 34 35 /* ========================================================================== */ 36 37 /* scaffold objects */ 38 static jlong timeout = 0; 39 40 /* test objects */ 41 static jthread thread = NULL; 42 43 /* event counts */ 44 static int SingleStepEventsCount = 0; 45 46 /* ========================================================================== */ 47 48 /** callback functions **/ 49 50 static void JNICALL 51 SingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 52 jmethodID method, jlocation location) { 53 char *name = NULL; 54 char *signature = NULL; 55 char buffer[32]; 56 57 SingleStepEventsCount++; 58 59 NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode, 60 jvmti_env, JVMTI_DISABLE, JVMTI_EVENT_SINGLE_STEP, NULL)); 61 62 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(GetMethodName, 63 jvmti_env, method, &name, &signature, NULL))) { 64 nsk_jvmti_setFailStatus(); 65 return; 66 } 67 NSK_DISPLAY3("SingleStep event: %s%s, location=%s\n", name, signature, 68 jlong_to_string(location, buffer)); 69 if (name != NULL) 70 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)name); 71 if (signature != NULL) 72 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)signature); 73 } 74 75 /* ========================================================================== */ 76 77 static int prepare(jvmtiEnv* jvmti, JNIEnv* jni) { 78 const char* THREAD_NAME = "Debuggee Thread"; 79 jvmtiThreadInfo info; 80 jthread *threads = NULL; 81 jint threads_count = 0; 82 int i; 83 84 NSK_DISPLAY0("Prepare: find tested thread\n"); 85 86 /* get all live threads */ 87 if (!NSK_JVMTI_VERIFY( 88 NSK_CPP_STUB3(GetAllThreads, jvmti, &threads_count, &threads))) 89 return NSK_FALSE; 90 91 if (!NSK_VERIFY(threads_count > 0 && threads != NULL)) 92 return NSK_FALSE; 93 94 /* find tested thread */ 95 for (i = 0; i < threads_count; i++) { 96 if (!NSK_VERIFY(threads[i] != NULL)) 97 return NSK_FALSE; 98 99 /* get thread information */ 100 if (!NSK_JVMTI_VERIFY( 101 NSK_CPP_STUB3(GetThreadInfo, jvmti, threads[i], &info))) 102 return NSK_FALSE; 103 104 NSK_DISPLAY3(" thread #%d (%s): %p\n", i, info.name, threads[i]); 105 106 /* find by name */ 107 if (info.name != NULL && (strcmp(info.name, THREAD_NAME) == 0)) { 108 thread = threads[i]; 109 } 110 } 111 112 if (!NSK_JNI_VERIFY(jni, (thread = 113 NSK_CPP_STUB2(NewGlobalRef, jni, thread)) != NULL)) 114 return NSK_FALSE; 115 116 /* deallocate threads list */ 117 if (!NSK_JVMTI_VERIFY( 118 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads))) 119 return NSK_FALSE; 120 121 return NSK_TRUE; 122 } 123 124 /* ========================================================================== */ 125 126 /** Agent algorithm. */ 127 static void JNICALL 128 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 129 130 if (!nsk_jvmti_waitForSync(timeout)) 131 return; 132 133 if (!prepare(jvmti, jni)) { 134 nsk_jvmti_setFailStatus(); 135 return; 136 } 137 138 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode, 139 jvmti, JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, thread))) 140 nsk_jvmti_setFailStatus(); 141 142 /* resume debugee and wait for sync */ 143 if (!nsk_jvmti_resumeSync()) 144 return; 145 if (!nsk_jvmti_waitForSync(timeout)) 146 return; 147 148 NSK_DISPLAY1("SingleStep events received: %d\n", 149 SingleStepEventsCount); 150 if (!NSK_VERIFY(SingleStepEventsCount != 0)) 151 nsk_jvmti_setFailStatus(); 152 153 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, thread)); 154 155 if (!nsk_jvmti_resumeSync()) 156 return; 157 } 158 159 /* ========================================================================== */ 160 161 /** Agent library initialization. */ 162 #ifdef STATIC_BUILD 163 JNIEXPORT jint JNICALL Agent_OnLoad_ma10t004(JavaVM *jvm, char *options, void *reserved) { 164 return Agent_Initialize(jvm, options, reserved); 165 } 166 JNIEXPORT jint JNICALL Agent_OnAttach_ma10t004(JavaVM *jvm, char *options, void *reserved) { 167 return Agent_Initialize(jvm, options, reserved); 168 } 169 JNIEXPORT jint JNI_OnLoad_ma10t004(JavaVM *jvm, char *options, void *reserved) { 170 return JNI_VERSION_1_8; 171 } 172 #endif 173 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 174 jvmtiEnv* jvmti = NULL; 175 jvmtiCapabilities caps; 176 jvmtiEventCallbacks callbacks; 177 178 NSK_DISPLAY0("Agent_OnLoad\n"); 179 180 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 181 return JNI_ERR; 182 183 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 184 185 if (!NSK_VERIFY((jvmti = 186 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 187 return JNI_ERR; 188 189 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 190 return JNI_ERR; 191 192 memset(&caps, 0, sizeof(caps)); 193 caps.can_generate_single_step_events = 1; 194 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) { 195 return JNI_ERR; 196 } 197 198 memset(&callbacks, 0, sizeof(callbacks)); 199 callbacks.SingleStep = &SingleStep; 200 if (!NSK_VERIFY(nsk_jvmti_init_MA(&callbacks))) 201 return JNI_ERR; 202 203 return JNI_OK; 204 } 205 206 /* ========================================================================== */ 207 208 }