1 /* 2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 #include "jni.h" 46 #include "jvmti.h" 47 48 #include "agent_util.h" 49 50 /* Create major.minor.micro version string */ 51 static void 52 version_check(jint cver, jint rver) 53 { 54 jint cmajor, cminor, cmicro; 55 jint rmajor, rminor, rmicro; 56 57 cmajor = (cver & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; 58 cminor = (cver & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; 59 cmicro = (cver & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; 60 rmajor = (rver & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; 61 rminor = (rver & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; 62 rmicro = (rver & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; 63 stdout_message("Compile Time JVMTI Version: %d.%d.%d (0x%08x)\n", 64 cmajor, cminor, cmicro, cver); 65 stdout_message("Run Time JVMTI Version: %d.%d.%d (0x%08x)\n", 66 rmajor, rminor, rmicro, rver); 67 if ( (cmajor > rmajor) || (cmajor == rmajor && cminor > rminor) ) { 68 fatal_error( 69 "ERROR: Compile Time JVMTI and Run Time JVMTI are incompatible\n"); 70 } 71 } 72 73 /* Callback for JVMTI_EVENT_VM_INIT */ 74 static void JNICALL 75 vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) 76 { 77 jvmtiError err; 78 jint runtime_version; 79 80 /* The exact JVMTI version doesn't have to match, however this 81 * code demonstrates how you can check that the JVMTI version seen 82 * in the jvmti.h include file matches that being supplied at runtime 83 * by the VM. 84 */ 85 err = (*jvmti)->GetVersionNumber(jvmti, &runtime_version); 86 check_jvmti_error(jvmti, err, "get version number"); 87 version_check(JVMTI_VERSION, runtime_version); 88 } 89 90 /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */ 91 JNIEXPORT jint JNICALL 92 Agent_OnLoad(JavaVM *vm, char *options, void *reserved) 93 { 94 jint rc; 95 jvmtiError err; 96 jvmtiEventCallbacks callbacks; 97 jvmtiEnv *jvmti; 98 99 /* Get JVMTI environment */ 100 rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION); 101 if (rc != JNI_OK) { 102 fatal_error("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc); 103 return -1; 104 } 105 106 /* Set callbacks and enable event notifications */ 107 memset(&callbacks, 0, sizeof(callbacks)); 108 callbacks.VMInit = &vm_init; 109 err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); 110 check_jvmti_error(jvmti, err, "set event callbacks"); 111 err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, 112 JVMTI_EVENT_VM_INIT, NULL); 113 check_jvmti_error(jvmti, err, "set event notify"); 114 return 0; 115 } 116 117 /* Agent_OnUnload() is called last */ 118 JNIEXPORT void JNICALL 119 Agent_OnUnload(JavaVM *vm) 120 { 121 }