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 <stdio.h>
25 #include <string.h>
26 #include <inttypes.h>
27 #include "jvmti.h"
28 #include "agent_common.h"
29 #include "JVMTITools.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #ifndef JNI_ENV_ARG
36
37 #ifdef __cplusplus
38 #define JNI_ENV_ARG(x, y) y
39 #define JNI_ENV_PTR(x) x
40 #else
41 #define JNI_ENV_ARG(x,y) x, y
42 #define JNI_ENV_PTR(x) (*x)
43 #endif
44
45 #endif
46
47 #define PASSED 0
48 #define STATUS_FAILED 2
49
50 #define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return
51
52 static jvmtiEnv *jvmti = NULL;
53 static jvmtiCapabilities caps;
54 static jvmtiEventCallbacks callbacks;
55 static jint errCode = PASSED;
56 static jboolean printdump = JNI_TRUE;
57
58 static jmethodID midRun = NULL;
59 static jmethodID midCountDownObject = NULL;
60 static jmethodID midCheckPoint = NULL;
61
62 static jint framesExpected = 0;
63 static jint framesCount = 0;
64 static jint methodExitEventCount = 0;
65
260 val_exp);
261 if (err != JVMTI_ERROR_NONE) {
262 printf("(ForceEarlyReturnObject) unexpected error: %s (%d)\n",
263 TranslateError(err), err);
264 RETURN_FAILED;
265 }
266 }
267 fflush(0);
268 }
269
270 void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread,
271 jmethodID method, jboolean was_popped_by_exception, jvalue value) {
272 jobject ret_val = value.l;
273
274 methodExitEventCount++;
275 printf("MethodExit event: methodExitEventCount=%d\n", methodExitEventCount);
276 if (method == midRun || method == midCheckPoint) {
277 return;
278 }
279 if (method == midCountDownObject) {
280 if (!JNI_ENV_PTR(env)->IsSameObject(JNI_ENV_ARG(env, ret_val), val_exp)) {
281 printf("Wrong ForceEarlyReturnObject return value: 0x%p\n", ret_val);
282 printf("expected: 0x%p\n", val_exp);
283 errCode = STATUS_FAILED;
284 }
285 if (was_popped_by_exception) {
286 printf("Method was_popped_by_exception unexpectedly\n");
287 errCode = STATUS_FAILED;
288 }
289 }
290 fflush(0);
291 }
292
293 #ifdef STATIC_BUILD
294 JNIEXPORT jint JNICALL Agent_OnLoad_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
295 return Agent_Initialize(jvm, options, reserved);
296 }
297 JNIEXPORT jint JNICALL Agent_OnAttach_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
298 return Agent_Initialize(jvm, options, reserved);
299 }
300 JNIEXPORT jint JNI_OnLoad_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
301 return JNI_VERSION_1_8;
302 }
303 #endif
304 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
305 jvmtiError err;
306 jint res;
307
308 if (options != NULL && strcmp(options, "printdump") == 0) {
309 printf("Printdump is turned on!\n");
310
311 printdump = JNI_TRUE;
312 }
313
314 res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
315 JVMTI_VERSION_1_1);
316 if (res != JNI_OK || jvmti == NULL) {
317 printf("Wrong error code from a valid call to GetEnv!\n");
318 return JNI_ERR;
319 }
320
321 err = jvmti->GetPotentialCapabilities(&caps);
322 if (err != JVMTI_ERROR_NONE) {
323 printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
324 TranslateError(err), err);
325 return JNI_ERR;
326 }
327
328 err = jvmti->AddCapabilities(&caps);
329 if (err != JVMTI_ERROR_NONE) {
330 printf("(AddCapabilities) unexpected error: %s (%d)\n",
331 TranslateError(err), err);
332 return JNI_ERR;
333 }
334
335 err = jvmti->GetCapabilities(&caps);
363 return JNI_OK;
364 }
365
366 JNIEXPORT void JNICALL
367 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_getReady(
368 JNIEnv *env, jclass c, jclass cls, jint depth, jobject ret_obj) {
369 jvmtiError err;
370
371 if (jvmti == NULL) {
372 printf("JVMTI client was not properly loaded!\n");
373 RETURN_FAILED;
374 }
375
376 if (!caps.can_force_early_return ||
377 !caps.can_generate_breakpoint_events ||
378 !caps.can_generate_method_exit_events ||
379 !caps.can_generate_single_step_events) {
380 return;
381 }
382
383 midRun = JNI_ENV_PTR(env)->GetMethodID(JNI_ENV_ARG(env, cls),
384 "run", "()V");
385 if (midRun == NULL) {
386 printf("Cannot find Method ID for method run\n");
387 RETURN_FAILED;
388 }
389
390 midCheckPoint = JNI_ENV_PTR(env)->GetMethodID(JNI_ENV_ARG(env, cls),
391 "checkPoint", "()V");
392 if (midCheckPoint == NULL) {
393 printf("Cannot find Method ID for method checkPoint\n");
394 RETURN_FAILED;
395 }
396
397 midCountDownObject = JNI_ENV_PTR(env)->GetMethodID(JNI_ENV_ARG(env, cls),
398 "countDownObject", sig_exp);
399 if (midCountDownObject == NULL) {
400 printf("Cannot find Method ID for method countDownObject\n");
401 RETURN_FAILED;
402 }
403
404 err = jvmti->SetBreakpoint(midCheckPoint, 0);
405 if (err != JVMTI_ERROR_NONE) {
406 printf("(SetBreakpoint) unexpected error: %s (%d)\n",
407 TranslateError(err), err);
408 RETURN_FAILED;
409 }
410
411 err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
412 JVMTI_EVENT_BREAKPOINT, NULL);
413 if (err != JVMTI_ERROR_NONE) {
414 printf("Failed to enable BREAKPOINT event: %s (%d)\n",
415 TranslateError(err), err);
416 RETURN_FAILED;
417 } else {
418 val_exp = JNI_ENV_PTR(env)->NewGlobalRef(JNI_ENV_ARG(env, ret_obj));
419 framesExpected = depth;
420 }
421 }
422
423 JNIEXPORT jint JNICALL
424 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_check(JNIEnv *env, jclass cls) {
425 if (framesCount != framesExpected) {
426 printf("Wrong number of returned early frames: %d, expected: %d\n",
427 framesCount, framesExpected);
428 errCode = STATUS_FAILED;
429 }
430 fflush(0);
431 return errCode;
432 }
433
434 JNIEXPORT void JNICALL
435 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_printObject(
436 JNIEnv *env, jclass cls, jobject obj) {
437
438 printf("\nReturned jobject: %#" PRIxPTR "\n", (uintptr_t)obj);
439 fflush(0);
440 return;
441 }
442
443 #ifdef __cplusplus
444 }
445 #endif
|
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 <stdio.h>
25 #include <string.h>
26 #include <inttypes.h>
27 #include "jvmti.h"
28 #include "agent_common.h"
29 #include "JVMTITools.h"
30
31 extern "C" {
32
33
34 #define PASSED 0
35 #define STATUS_FAILED 2
36
37 #define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return
38
39 static jvmtiEnv *jvmti = NULL;
40 static jvmtiCapabilities caps;
41 static jvmtiEventCallbacks callbacks;
42 static jint errCode = PASSED;
43 static jboolean printdump = JNI_TRUE;
44
45 static jmethodID midRun = NULL;
46 static jmethodID midCountDownObject = NULL;
47 static jmethodID midCheckPoint = NULL;
48
49 static jint framesExpected = 0;
50 static jint framesCount = 0;
51 static jint methodExitEventCount = 0;
52
247 val_exp);
248 if (err != JVMTI_ERROR_NONE) {
249 printf("(ForceEarlyReturnObject) unexpected error: %s (%d)\n",
250 TranslateError(err), err);
251 RETURN_FAILED;
252 }
253 }
254 fflush(0);
255 }
256
257 void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread,
258 jmethodID method, jboolean was_popped_by_exception, jvalue value) {
259 jobject ret_val = value.l;
260
261 methodExitEventCount++;
262 printf("MethodExit event: methodExitEventCount=%d\n", methodExitEventCount);
263 if (method == midRun || method == midCheckPoint) {
264 return;
265 }
266 if (method == midCountDownObject) {
267 if (!env->IsSameObject(ret_val, val_exp)) {
268 printf("Wrong ForceEarlyReturnObject return value: 0x%p\n", ret_val);
269 printf("expected: 0x%p\n", val_exp);
270 errCode = STATUS_FAILED;
271 }
272 if (was_popped_by_exception) {
273 printf("Method was_popped_by_exception unexpectedly\n");
274 errCode = STATUS_FAILED;
275 }
276 }
277 fflush(0);
278 }
279
280 #ifdef STATIC_BUILD
281 JNIEXPORT jint JNICALL Agent_OnLoad_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
282 return Agent_Initialize(jvm, options, reserved);
283 }
284 JNIEXPORT jint JNICALL Agent_OnAttach_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
285 return Agent_Initialize(jvm, options, reserved);
286 }
287 JNIEXPORT jint JNI_OnLoad_earlyretobj(JavaVM *jvm, char *options, void *reserved) {
288 return JNI_VERSION_1_8;
289 }
290 #endif
291 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
292 jvmtiError err;
293 jint res;
294
295 if (options != NULL && strcmp(options, "printdump") == 0) {
296 printf("Printdump is turned on!\n");
297
298 printdump = JNI_TRUE;
299 }
300
301 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
302 if (res != JNI_OK || jvmti == NULL) {
303 printf("Wrong error code from a valid call to GetEnv!\n");
304 return JNI_ERR;
305 }
306
307 err = jvmti->GetPotentialCapabilities(&caps);
308 if (err != JVMTI_ERROR_NONE) {
309 printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
310 TranslateError(err), err);
311 return JNI_ERR;
312 }
313
314 err = jvmti->AddCapabilities(&caps);
315 if (err != JVMTI_ERROR_NONE) {
316 printf("(AddCapabilities) unexpected error: %s (%d)\n",
317 TranslateError(err), err);
318 return JNI_ERR;
319 }
320
321 err = jvmti->GetCapabilities(&caps);
349 return JNI_OK;
350 }
351
352 JNIEXPORT void JNICALL
353 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_getReady(
354 JNIEnv *env, jclass c, jclass cls, jint depth, jobject ret_obj) {
355 jvmtiError err;
356
357 if (jvmti == NULL) {
358 printf("JVMTI client was not properly loaded!\n");
359 RETURN_FAILED;
360 }
361
362 if (!caps.can_force_early_return ||
363 !caps.can_generate_breakpoint_events ||
364 !caps.can_generate_method_exit_events ||
365 !caps.can_generate_single_step_events) {
366 return;
367 }
368
369 midRun = env->GetMethodID(cls, "run", "()V");
370 if (midRun == NULL) {
371 printf("Cannot find Method ID for method run\n");
372 RETURN_FAILED;
373 }
374
375 midCheckPoint = env->GetMethodID(cls, "checkPoint", "()V");
376 if (midCheckPoint == NULL) {
377 printf("Cannot find Method ID for method checkPoint\n");
378 RETURN_FAILED;
379 }
380
381 midCountDownObject = env->GetMethodID(cls, "countDownObject", sig_exp);
382 if (midCountDownObject == NULL) {
383 printf("Cannot find Method ID for method countDownObject\n");
384 RETURN_FAILED;
385 }
386
387 err = jvmti->SetBreakpoint(midCheckPoint, 0);
388 if (err != JVMTI_ERROR_NONE) {
389 printf("(SetBreakpoint) unexpected error: %s (%d)\n",
390 TranslateError(err), err);
391 RETURN_FAILED;
392 }
393
394 err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
395 JVMTI_EVENT_BREAKPOINT, NULL);
396 if (err != JVMTI_ERROR_NONE) {
397 printf("Failed to enable BREAKPOINT event: %s (%d)\n",
398 TranslateError(err), err);
399 RETURN_FAILED;
400 } else {
401 val_exp = env->NewGlobalRef(ret_obj);
402 framesExpected = depth;
403 }
404 }
405
406 JNIEXPORT jint JNICALL
407 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_check(JNIEnv *env, jclass cls) {
408 if (framesCount != framesExpected) {
409 printf("Wrong number of returned early frames: %d, expected: %d\n",
410 framesCount, framesExpected);
411 errCode = STATUS_FAILED;
412 }
413 fflush(0);
414 return errCode;
415 }
416
417 JNIEXPORT void JNICALL
418 Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_printObject(
419 JNIEnv *env, jclass cls, jobject obj) {
420
421 printf("\nReturned jobject: %#" PRIxPTR "\n", (uintptr_t)obj);
422 fflush(0);
423 return;
424 }
425
426 }
|