rev 52100 : 8212082: Remove the NSK_CPP_STUB macros for remaining vmTestbase/jvmti/[sS]* Summary: Reviewed-by:
1 /* 2 * Copyright (c) 2003, 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 <string.h> 25 #include "jvmti.h" 26 #include "agent_common.h" 27 #include "jni_tools.h" 28 #include "jvmti_tools.h" 29 30 extern "C" { 31 32 /* ============================================================================= */ 33 34 /* scaffold objects */ 35 static JNIEnv* jni = NULL; 36 static jvmtiEnv *jvmti = NULL; 37 static jlong timeout = 0; 38 39 /* constants */ 40 #define THREADS_COUNT 6 41 #define MAX_NAME_LENGTH 100 42 #define MAX_STACK_SIZE 100 43 44 /* thread description structure */ 45 typedef struct { 46 char threadName[MAX_NAME_LENGTH]; 47 char methodName[MAX_NAME_LENGTH]; 48 char methodSig[MAX_NAME_LENGTH]; 49 jthread thread; 50 jclass cls; 51 jmethodID method; 52 jlocation location; 53 } ThreadDesc; 54 55 /* descriptions of tested threads */ 56 static ThreadDesc threadsDesc[THREADS_COUNT] = { 57 {"threadRunning", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}, 58 {"threadEntering", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}, 59 {"threadWaiting", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}, 60 {"threadSleeping", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}, 61 {"threadRunningInterrupted", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}, 62 {"threadRunningNative", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION} 63 }; 64 65 /* indexes of known threads */ 66 static const int interruptedThreadIndex = THREADS_COUNT - 2; 67 static const int nativeThreadIndex = THREADS_COUNT - 1; 68 69 /* ============================================================================= */ 70 71 /* testcase(s) */ 72 static int prepare(); 73 static int checkThreads(int suspended, const char* kind); 74 static int suspendThreadsIndividually(int suspend); 75 static int clean(); 76 77 /* ============================================================================= */ 78 79 /** Agent algorithm. */ 80 static void JNICALL 81 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 82 jni = agentJNI; 83 84 /* wait for initial sync */ 85 if (!nsk_jvmti_waitForSync(timeout)) 86 return; 87 88 /* perform testcase(s) */ 89 { 90 /* prepare data: find threads */ 91 NSK_DISPLAY0("Prepare data\n"); 92 if (!prepare()) { 93 nsk_jvmti_setFailStatus(); 94 return; 95 } 96 97 /* testcase #1: check not suspended threads */ 98 NSK_DISPLAY0("Testcase #1: check stack frames of not suspended threads\n"); 99 if (!checkThreads(NSK_FALSE, "not suspended")) 100 return; 101 102 /* suspend threads */ 103 NSK_DISPLAY0("Suspend each thread\n"); 104 if (!suspendThreadsIndividually(NSK_TRUE)) 105 return; 106 107 /* testcase #2: check suspended threads */ 108 NSK_DISPLAY0("Testcase #2: check stack frames of suspended threads\n"); 109 if (!checkThreads(NSK_TRUE, "suspended")) 110 return; 111 112 /* resume threads */ 113 NSK_DISPLAY0("Resume each thread\n"); 114 if (!suspendThreadsIndividually(NSK_FALSE)) 115 return; 116 117 /* testcase #3: check resumed threads */ 118 NSK_DISPLAY0("Testcase #3: check stack frames of resumed threads\n"); 119 if (!checkThreads(NSK_FALSE, "resumed")) 120 return; 121 122 /* clean date: delete threads references */ 123 NSK_DISPLAY0("Clean data\n"); 124 if (!clean()) { 125 nsk_jvmti_setFailStatus(); 126 return; 127 } 128 } 129 130 /* resume debugee after last sync */ 131 if (!nsk_jvmti_resumeSync()) 132 return; 133 } 134 135 /* ============================================================================= */ 136 137 /** 138 * Prepare data: 139 * - clean threads list 140 * - get all live threads 141 * - get threads name 142 * - find tested threads 143 * - make global refs 144 */ 145 static int prepare() { 146 jthread *allThreadsList = NULL; 147 jint allThreadsCount = 0; 148 int found = 0; 149 int i; 150 151 NSK_DISPLAY1("Find tested threads: %d\n", THREADS_COUNT); 152 153 /* clean threads list */ 154 for (i = 0; i < THREADS_COUNT; i++) { 155 threadsDesc[i].thread = (jthread)NULL; 156 threadsDesc[i].method = (jmethodID)NULL; 157 threadsDesc[i].location = NSK_JVMTI_INVALID_JLOCATION; 158 } 159 160 /* get all live threads */ 161 if (!NSK_JVMTI_VERIFY( 162 NSK_CPP_STUB3(GetAllThreads, jvmti, &allThreadsCount, &allThreadsList))) 163 return NSK_FALSE; 164 165 if (!NSK_VERIFY(allThreadsCount > 0 && allThreadsList != NULL)) 166 return NSK_FALSE; 167 168 /* find tested threads */ 169 for (i = 0; i < allThreadsCount; i++) { 170 jvmtiThreadInfo threadInfo; 171 172 if (!NSK_VERIFY(allThreadsList[i] != NULL)) 173 return NSK_FALSE; 174 175 /* get thread name (info) */ 176 if (!NSK_JVMTI_VERIFY( 177 NSK_CPP_STUB3(GetThreadInfo, jvmti, allThreadsList[i], &threadInfo))) 178 return NSK_FALSE; 179 180 /* find by name */ 181 if (threadInfo.name != NULL) { 182 int j; 183 184 for (j = 0; j < THREADS_COUNT; j++) { 185 if (strcmp(threadInfo.name, threadsDesc[j].threadName) == 0) { 186 threadsDesc[j].thread = allThreadsList[i]; 187 NSK_DISPLAY3(" thread #%d (%s): %p\n", 188 j, threadInfo.name, (void*)threadsDesc[j].thread); 189 } 190 } 191 } 192 } 193 194 /* deallocate all threads list */ 195 if (!NSK_JVMTI_VERIFY( 196 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)allThreadsList))) 197 return NSK_FALSE; 198 199 /* check if all tested threads found */ 200 found = 0; 201 for (i = 0; i < THREADS_COUNT; i++) { 202 if (threadsDesc[i].thread == NULL) { 203 NSK_COMPLAIN2("Not found tested thread #%d (%s)\n", i, threadsDesc[i].threadName); 204 } else { 205 found++; 206 } 207 } 208 209 if (found < THREADS_COUNT) 210 return NSK_FALSE; 211 212 /* get threads class and frame method */ 213 NSK_DISPLAY0("Find tested methods:\n"); 214 for (i = 0; i < THREADS_COUNT; i++) { 215 /* get thread class */ 216 if (!NSK_JNI_VERIFY(jni, (threadsDesc[i].cls = 217 NSK_CPP_STUB2(GetObjectClass, jni, threadsDesc[i].thread)) != NULL)) 218 return NSK_FALSE; 219 /* get frame method */ 220 if (!NSK_JNI_VERIFY(jni, (threadsDesc[i].method = 221 NSK_CPP_STUB4(GetMethodID, jni, threadsDesc[i].cls, 222 threadsDesc[i].methodName, threadsDesc[i].methodSig)) != NULL)) 223 return NSK_FALSE; 224 225 NSK_DISPLAY4(" thread #%d (%s): %p (%s)\n", 226 i, threadsDesc[i].threadName, 227 (void*)threadsDesc[i].method, 228 threadsDesc[i].methodName); 229 } 230 231 /* make global refs */ 232 for (i = 0; i < THREADS_COUNT; i++) { 233 if (!NSK_JNI_VERIFY(jni, (threadsDesc[i].thread = (jthread) 234 NSK_CPP_STUB2(NewGlobalRef, jni, threadsDesc[i].thread)) != NULL)) 235 return NSK_FALSE; 236 if (!NSK_JNI_VERIFY(jni, (threadsDesc[i].cls = (jclass) 237 NSK_CPP_STUB2(NewGlobalRef, jni, threadsDesc[i].cls)) != NULL)) 238 return NSK_FALSE; 239 } 240 241 return NSK_TRUE; 242 } 243 244 /** 245 * Suspend or resume tested threads. 246 */ 247 static int suspendThreadsIndividually(int suspend) { 248 int i; 249 250 for (i = 0; i < THREADS_COUNT; i++) { 251 if (suspend) { 252 NSK_DISPLAY2(" suspend thread #%d (%s)\n", i, threadsDesc[i].threadName); 253 if (!NSK_JVMTI_VERIFY( 254 NSK_CPP_STUB2(SuspendThread, jvmti, threadsDesc[i].thread))) 255 nsk_jvmti_setFailStatus(); 256 } else { 257 NSK_DISPLAY2(" resume thread #%d (%s)\n", i, threadsDesc[i].threadName); 258 if (!NSK_JVMTI_VERIFY( 259 NSK_CPP_STUB2(ResumeThread, jvmti, threadsDesc[i].thread))) 260 nsk_jvmti_setFailStatus(); 261 } 262 } 263 return NSK_TRUE; 264 } 265 266 /** 267 * Testcase: check tested threads 268 * - call GetFrameCount() and getStackTrace() 269 * - for suspended thread compare number of stack frames returned 270 * - find stack frames with expected methodID 271 * 272 * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break. 273 */ 274 static int checkThreads(int suspended, const char* kind) { 275 int i; 276 277 /* check each thread */ 278 for (i = 0; i < THREADS_COUNT; i++) { 279 jint frameCount = 0; 280 jint frameStackSize = 0; 281 jvmtiFrameInfo frameStack[MAX_STACK_SIZE]; 282 int found = 0; 283 int j; 284 285 NSK_DISPLAY2(" thread #%d (%s):\n", i, threadsDesc[i].threadName); 286 287 /* get frame count */ 288 if (!NSK_JVMTI_VERIFY( 289 NSK_CPP_STUB3(GetFrameCount, jvmti, 290 threadsDesc[i].thread, &frameCount))) { 291 nsk_jvmti_setFailStatus(); 292 return NSK_TRUE; 293 } 294 295 NSK_DISPLAY1(" frameCount: %d\n", (int)frameCount); 296 297 /* get stack trace */ 298 if (!NSK_JVMTI_VERIFY( 299 NSK_CPP_STUB6(GetStackTrace, jvmti, threadsDesc[i].thread, 300 0, MAX_STACK_SIZE, frameStack, &frameStackSize))) { 301 nsk_jvmti_setFailStatus(); 302 return NSK_TRUE; 303 } 304 305 NSK_DISPLAY1(" stack depth: %d\n", (int)frameStackSize); 306 307 /* Only check for suspended threads: running threads might have different 308 frames between stack grabbing calls. */ 309 if (suspended && (frameStackSize != frameCount)) { 310 NSK_COMPLAIN5("Different frames count for %s thread #%d (%s):\n" 311 "# getStackTrace(): %d\n" 312 "# getFrameCount(): %d\n", 313 kind, i, threadsDesc[i].threadName, 314 (int)frameStackSize, (int)frameCount); 315 nsk_jvmti_setFailStatus(); 316 } 317 318 /* find method on the stack */ 319 found = 0; 320 for (j = 0; j < frameStackSize; j++) { 321 NSK_DISPLAY3(" %d: methodID: %p, location: %ld\n", 322 j, (void*)frameStack[j].method, 323 (long)frameStack[j].location); 324 /* check frame method */ 325 if (frameStack[j].method == NULL) { 326 NSK_COMPLAIN3("NULL methodID in stack for %s thread #%d (%s)\n", 327 kind, i, threadsDesc[i].threadName); 328 nsk_jvmti_setFailStatus(); 329 } else if (frameStack[j].method == threadsDesc[i].method) { 330 found++; 331 NSK_DISPLAY1(" found expected method: %s\n", 332 (void*)threadsDesc[i].methodName); 333 } 334 } 335 336 /* check if expected method found */ 337 if (found != 1) { 338 NSK_COMPLAIN5("Unexpected method frames on stack for %s thread #%d (%s):\n" 339 "# found frames: %d\n" 340 "# expected: %d\n", 341 kind, i, threadsDesc[i].threadName, 342 found, 1); 343 nsk_jvmti_setFailStatus(); 344 } 345 } 346 347 /* test may continue */ 348 return NSK_TRUE; 349 } 350 351 /** 352 * Clean data: 353 * - dispose global references to tested threads 354 */ 355 static int clean() { 356 int i; 357 358 /* dispose global references to threads */ 359 for (i = 0; i < THREADS_COUNT; i++) { 360 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threadsDesc[i].thread)); 361 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threadsDesc[i].cls)); 362 } 363 364 return NSK_TRUE; 365 } 366 367 /* ============================================================================= */ 368 369 static volatile int testedThreadRunning = NSK_FALSE; 370 static volatile int testedThreadShouldFinish = NSK_FALSE; 371 372 /** Native running method in tested thread. */ 373 JNIEXPORT void JNICALL 374 Java_nsk_jvmti_scenarios_sampling_SP02_sp02t002ThreadRunningNative_testedMethod(JNIEnv* jni, 375 jobject obj) { 376 volatile int i = 0, n = 1000; 377 378 /* run in a loop */ 379 testedThreadRunning = NSK_TRUE; 380 while (!testedThreadShouldFinish) { 381 if (n <= 0) 382 n = 1000; 383 if (i >= n) 384 i = 0; 385 i++; 386 } 387 testedThreadRunning = NSK_FALSE; 388 } 389 390 /** Wait for native method is running. */ 391 JNIEXPORT jboolean JNICALL 392 Java_nsk_jvmti_scenarios_sampling_SP02_sp02t002ThreadRunningNative_checkReady(JNIEnv* jni, 393 jobject obj) { 394 while (!testedThreadRunning) { 395 nsk_jvmti_sleep(1000); 396 } 397 return testedThreadRunning ? JNI_TRUE : JNI_FALSE; 398 } 399 400 /** Let native method to finish. */ 401 JNIEXPORT void JNICALL 402 Java_nsk_jvmti_scenarios_sampling_SP02_sp02t002ThreadRunningNative_letFinish(JNIEnv* jni, 403 jobject obj) { 404 testedThreadShouldFinish = NSK_TRUE; 405 } 406 407 /* ============================================================================= */ 408 409 /** Agent library initialization. */ 410 #ifdef STATIC_BUILD 411 JNIEXPORT jint JNICALL Agent_OnLoad_sp02t002(JavaVM *jvm, char *options, void *reserved) { 412 return Agent_Initialize(jvm, options, reserved); 413 } 414 JNIEXPORT jint JNICALL Agent_OnAttach_sp02t002(JavaVM *jvm, char *options, void *reserved) { 415 return Agent_Initialize(jvm, options, reserved); 416 } 417 JNIEXPORT jint JNI_OnLoad_sp02t002(JavaVM *jvm, char *options, void *reserved) { 418 return JNI_VERSION_1_8; 419 } 420 #endif 421 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 422 423 /* init framework and parse options */ 424 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 425 return JNI_ERR; 426 427 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 428 429 /* create JVMTI environment */ 430 if (!NSK_VERIFY((jvmti = 431 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 432 return JNI_ERR; 433 434 /* add specific capabilities for suspending thread */ 435 { 436 jvmtiCapabilities suspendCaps; 437 memset(&suspendCaps, 0, sizeof(suspendCaps)); 438 suspendCaps.can_suspend = 1; 439 if (!NSK_JVMTI_VERIFY( 440 NSK_CPP_STUB2(AddCapabilities, jvmti, &suspendCaps))) 441 return JNI_ERR; 442 } 443 444 /* register agent proc and arg */ 445 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 446 return JNI_ERR; 447 448 return JNI_OK; 449 } 450 451 /* ============================================================================= */ 452 453 } --- EOF ---