45 #else 46 #define JNI_ENV_ARG(x, y) x, y 47 #define JNI_ENV_PTR(x) (*x) 48 #endif 49 #endif 50 51 #ifndef JNI_ENV_ARG1 52 #ifdef __cplusplus 53 #define JNI_ENV_ARG1(x) 54 #else 55 #define JNI_ENV_ARG1(x) x 56 #endif 57 #endif 58 59 #define PASSED 0 60 #define STATUS_FAILED 2 61 62 #define TRIES 30 63 #define MAX_THREADS 5 64 65 static const char *javaField = "_ji06t001a"; 66 static const char *classSig = 67 "Lnsk/jvmti/scenarios/jni_interception/JI06/ji06t001a;"; 68 69 static JavaVM *vm; 70 static jvmtiEnv *jvmti = NULL; 71 72 static volatile int verbose = 0; 73 74 static volatile jint result = PASSED; 75 static volatile int monEntered = 0; /* the monitor entered */ 76 static volatile int thrStarted[MAX_THREADS]; /* a thread started */ 77 static volatile int releaseMon = 0; /* flag to release the monitor */ 78 79 static volatile jobject clsObj; 80 static jrawMonitorID countLock; 81 82 /* the original JNI function table */ 83 static jniNativeInterface *orig_jni_functions = NULL; 84 208 /* 4932877 fix in accordance with ANSI C: thread context of type void* -> int* -> int */ 209 int indx = *((int *) context); 210 211 NSK_DISPLAY1("waitingThread: thread #%d started\n\ 212 \tattaching the thread to the VM ...\n", 213 indx); 214 if ((res = 215 JNI_ENV_PTR(vm)->AttachCurrentThread( 216 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 217 NSK_COMPLAIN1("TEST FAILURE: waitingThread: AttachCurrentThread() returns: %d\n", 218 res); 219 return STATUS_FAILED; 220 } 221 222 NSK_DISPLAY1("waitingThread: thread #%d is trying to enter the monitor ...\n", 223 indx); 224 225 thrStarted[indx-1] = 1; /* the thread is started */ 226 227 if (enterMonitor(env, "waitingThread") == STATUS_FAILED) 228 return STATUS_FAILED; 229 if (verbose) 230 printf("waitingThread: thread #%d entered the monitor\n", 231 indx); 232 if (exitMonitor(env, "waitingThread") == STATUS_FAILED) 233 return STATUS_FAILED; 234 235 NSK_DISPLAY2("waitingThread: thread #%d exits the monitor\n\treturning %d\n", 236 indx, exitCode); 237 return exitCode; 238 } 239 240 static int ownerThread(void *context) { 241 JNIEnv *env; 242 int exitCode = PASSED; 243 jint res; 244 int tries = 0; 245 246 NSK_DISPLAY0("ownerThread: thread started\n\tattaching the thread to the VM ...\n"); 247 if ((res = 248 JNI_ENV_PTR(vm)->AttachCurrentThread( 249 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 250 NSK_COMPLAIN1("TEST FAILURE: ownerThread: AttachCurrentThread() returns: %d\n", 251 res); 252 return STATUS_FAILED; 253 } 254 255 NSK_DISPLAY0("ownerThread: trying to enter the monitor ...\n"); 256 if (enterMonitor(env, "ownerThread") == STATUS_FAILED) 257 return STATUS_FAILED; 258 259 monEntered = 1; /* the monitor has been entered */ 260 NSK_DISPLAY1("ownerThread: entered the monitor: monEntered=%d\n\ 261 \twaiting ...\n", 262 monEntered); 263 do { 264 THREAD_sleep(1); 265 tries++; 266 if (tries > TRIES) { 267 NSK_COMPLAIN1("TEST FAILED: ownerThread: time exceed after %d attempts\n", 268 TRIES); 269 JNI_ENV_PTR(env)->FatalError(JNI_ENV_ARG(env, 270 "ownerThread: time exceed")); 271 } 272 } while(releaseMon != 1); 273 274 if (exitMonitor(env, "ownerThread") == STATUS_FAILED) 275 return STATUS_FAILED; 276 277 NSK_DISPLAY1("ownerThread: exits the monitor\n\treturning %d\n", 278 exitCode); 279 280 return exitCode; 281 } 282 283 static int redirectorThread(void *context) { 284 JNIEnv *env; 285 int exitCode = PASSED; 286 jint res; 287 int tries = 0; 288 289 NSK_DISPLAY0("redirectorThread: thread started\n\tattaching the thread to the VM ...\n"); 290 if ((res = 291 JNI_ENV_PTR(vm)->AttachCurrentThread( 292 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 293 NSK_COMPLAIN1("TEST FAILURE: redirectorThread: AttachCurrentThread() returns: %d\n", 294 res); 295 return STATUS_FAILED; 296 } 297 298 NSK_DISPLAY0("redirectorThread: trying to redirect the MonitorEnter() ...\n"); 299 doRedirect(env); 300 301 NSK_DISPLAY1("redirectorThread: the MonitorEnter() redirected\n\treturning %d\n", 302 exitCode); 303 304 return exitCode; 305 } 306 /*********************/ 307 308 static jobject getObjectFromField(JNIEnv *env, jobject obj) { 309 jfieldID fid; 310 jclass _objCls; 311 312 _objCls = JNI_ENV_PTR(env)->GetObjectClass(JNI_ENV_ARG(env, obj)); 313 314 NSK_DISPLAY2("getObjectFromField: obtaining field ID for name=\"%s\" signature=\"%s\"...\n", 315 javaField, classSig); 316 if ((fid = JNI_ENV_PTR(env)->GetFieldID( 317 JNI_ENV_ARG(env, _objCls), javaField, classSig)) == 0) { 318 result = STATUS_FAILED; 319 NSK_COMPLAIN1("TEST FAILURE: failed to get ID for the field \"%s\"\n", 320 javaField); 321 JNI_ENV_PTR(env)->FatalError(JNI_ENV_ARG(env, 322 "failed to get ID for the java field")); 323 } 324 | 45 #else 46 #define JNI_ENV_ARG(x, y) x, y 47 #define JNI_ENV_PTR(x) (*x) 48 #endif 49 #endif 50 51 #ifndef JNI_ENV_ARG1 52 #ifdef __cplusplus 53 #define JNI_ENV_ARG1(x) 54 #else 55 #define JNI_ENV_ARG1(x) x 56 #endif 57 #endif 58 59 #define PASSED 0 60 #define STATUS_FAILED 2 61 62 #define TRIES 30 63 #define MAX_THREADS 5 64 65 // Helper for thread detach and terminate 66 #define THREAD_return(status) \ 67 do { \ 68 int res = JNI_ENV_PTR(vm)->DetachCurrentThread(JNI_ENV_ARG1(vm)); \ 69 if (res != 0) \ 70 NSK_COMPLAIN1("TEST WARNING: DetachCurrentThread() returns: %d\n", res); \ 71 else \ 72 NSK_DISPLAY0("Detaching thread ...\n"); \ 73 return status; \ 74 } while (0) 75 76 77 static const char *javaField = "_ji06t001a"; 78 static const char *classSig = 79 "Lnsk/jvmti/scenarios/jni_interception/JI06/ji06t001a;"; 80 81 static JavaVM *vm; 82 static jvmtiEnv *jvmti = NULL; 83 84 static volatile int verbose = 0; 85 86 static volatile jint result = PASSED; 87 static volatile int monEntered = 0; /* the monitor entered */ 88 static volatile int thrStarted[MAX_THREADS]; /* a thread started */ 89 static volatile int releaseMon = 0; /* flag to release the monitor */ 90 91 static volatile jobject clsObj; 92 static jrawMonitorID countLock; 93 94 /* the original JNI function table */ 95 static jniNativeInterface *orig_jni_functions = NULL; 96 220 /* 4932877 fix in accordance with ANSI C: thread context of type void* -> int* -> int */ 221 int indx = *((int *) context); 222 223 NSK_DISPLAY1("waitingThread: thread #%d started\n\ 224 \tattaching the thread to the VM ...\n", 225 indx); 226 if ((res = 227 JNI_ENV_PTR(vm)->AttachCurrentThread( 228 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 229 NSK_COMPLAIN1("TEST FAILURE: waitingThread: AttachCurrentThread() returns: %d\n", 230 res); 231 return STATUS_FAILED; 232 } 233 234 NSK_DISPLAY1("waitingThread: thread #%d is trying to enter the monitor ...\n", 235 indx); 236 237 thrStarted[indx-1] = 1; /* the thread is started */ 238 239 if (enterMonitor(env, "waitingThread") == STATUS_FAILED) 240 THREAD_return(STATUS_FAILED); 241 if (verbose) 242 printf("waitingThread: thread #%d entered the monitor\n", 243 indx); 244 if (exitMonitor(env, "waitingThread") == STATUS_FAILED) 245 THREAD_return(STATUS_FAILED); 246 247 NSK_DISPLAY2("waitingThread: thread #%d exits the monitor\n\treturning %d\n", 248 indx, exitCode); 249 THREAD_return(exitCode); 250 } 251 252 static int ownerThread(void *context) { 253 JNIEnv *env; 254 int exitCode = PASSED; 255 jint res; 256 int tries = 0; 257 258 NSK_DISPLAY0("ownerThread: thread started\n\tattaching the thread to the VM ...\n"); 259 if ((res = 260 JNI_ENV_PTR(vm)->AttachCurrentThread( 261 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 262 NSK_COMPLAIN1("TEST FAILURE: ownerThread: AttachCurrentThread() returns: %d\n", 263 res); 264 return STATUS_FAILED; 265 } 266 267 NSK_DISPLAY0("ownerThread: trying to enter the monitor ...\n"); 268 if (enterMonitor(env, "ownerThread") == STATUS_FAILED) 269 THREAD_return(STATUS_FAILED); 270 271 monEntered = 1; /* the monitor has been entered */ 272 NSK_DISPLAY1("ownerThread: entered the monitor: monEntered=%d\n\ 273 \twaiting ...\n", 274 monEntered); 275 do { 276 THREAD_sleep(1); 277 tries++; 278 if (tries > TRIES) { 279 NSK_COMPLAIN1("TEST FAILED: ownerThread: time exceed after %d attempts\n", 280 TRIES); 281 JNI_ENV_PTR(env)->FatalError(JNI_ENV_ARG(env, 282 "ownerThread: time exceed")); 283 } 284 } while(releaseMon != 1); 285 286 if (exitMonitor(env, "ownerThread") == STATUS_FAILED) 287 THREAD_return(STATUS_FAILED); 288 289 NSK_DISPLAY1("ownerThread: exits the monitor\n\treturning %d\n", 290 exitCode); 291 292 THREAD_return(exitCode); 293 } 294 295 static int redirectorThread(void *context) { 296 JNIEnv *env; 297 int exitCode = PASSED; 298 jint res; 299 int tries = 0; 300 301 NSK_DISPLAY0("redirectorThread: thread started\n\tattaching the thread to the VM ...\n"); 302 if ((res = 303 JNI_ENV_PTR(vm)->AttachCurrentThread( 304 JNI_ENV_ARG(vm, (void **) &env), (void *) 0)) != 0) { 305 NSK_COMPLAIN1("TEST FAILURE: redirectorThread: AttachCurrentThread() returns: %d\n", 306 res); 307 return STATUS_FAILED; 308 } 309 310 NSK_DISPLAY0("redirectorThread: trying to redirect the MonitorEnter() ...\n"); 311 doRedirect(env); 312 313 NSK_DISPLAY1("redirectorThread: the MonitorEnter() redirected\n\treturning %d\n", 314 exitCode); 315 316 THREAD_return(exitCode); 317 } 318 /*********************/ 319 320 static jobject getObjectFromField(JNIEnv *env, jobject obj) { 321 jfieldID fid; 322 jclass _objCls; 323 324 _objCls = JNI_ENV_PTR(env)->GetObjectClass(JNI_ENV_ARG(env, obj)); 325 326 NSK_DISPLAY2("getObjectFromField: obtaining field ID for name=\"%s\" signature=\"%s\"...\n", 327 javaField, classSig); 328 if ((fid = JNI_ENV_PTR(env)->GetFieldID( 329 JNI_ENV_ARG(env, _objCls), javaField, classSig)) == 0) { 330 result = STATUS_FAILED; 331 NSK_COMPLAIN1("TEST FAILURE: failed to get ID for the field \"%s\"\n", 332 javaField); 333 JNI_ENV_PTR(env)->FatalError(JNI_ENV_ARG(env, 334 "failed to get ID for the java field")); 335 } 336 |