test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodEntry/mentry001/mentry001.c
changeset 50260 46c67f5e27c2
equal deleted inserted replaced
50259:01d27ae7a84e 50260:46c67f5e27c2
       
     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 <inttypes.h>
       
    25 #include <stdio.h>
       
    26 #include <string.h>
       
    27 #include "jvmti.h"
       
    28 #include "agent_common.h"
       
    29 #include "jni_tools.h"
       
    30 #include "JVMTITools.h"
       
    31 
       
    32 #ifdef __cplusplus
       
    33 extern "C" {
       
    34 #endif
       
    35 
       
    36 #ifndef JNI_ENV_ARG
       
    37 
       
    38 #ifdef __cplusplus
       
    39 #define JNI_ENV_ARG(x, y) y
       
    40 #define JNI_ENV_PTR(x) x
       
    41 #else
       
    42 #define JNI_ENV_ARG(x,y) x, y
       
    43 #define JNI_ENV_PTR(x) (*x)
       
    44 #endif
       
    45 
       
    46 #endif
       
    47 
       
    48 #define PASSED 0
       
    49 #define STATUS_FAILED 2
       
    50 
       
    51 typedef struct {
       
    52     char *name;
       
    53     char *sig;
       
    54     jlocation loc;
       
    55 } entry_info;
       
    56 
       
    57 static jvmtiEnv *jvmti = NULL;
       
    58 static jvmtiCapabilities caps;
       
    59 static jvmtiEventCallbacks callbacks;
       
    60 static jint result = PASSED;
       
    61 static jboolean printdump = JNI_FALSE;
       
    62 static size_t eventsExpected = 0;
       
    63 static size_t eventsCount = 0;
       
    64 static entry_info entries[] = {
       
    65     {"check", "()I", -1},
       
    66     {"dummy", "()V", 0},
       
    67     {"chain", "()V", -1}
       
    68 };
       
    69 
       
    70 void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
       
    71         jthread thr, jmethodID method) {
       
    72     jvmtiError err;
       
    73     char *cls_sig, *generic;
       
    74     entry_info entry;
       
    75     jclass cls;
       
    76     jmethodID mid;
       
    77     char buffer[32];
       
    78 
       
    79     err = (*jvmti_env)->GetMethodDeclaringClass(jvmti_env, method, &cls);
       
    80     if (err != JVMTI_ERROR_NONE) {
       
    81         printf("(GetMethodDeclaringClass) unexpected error: %s (%d)\n",
       
    82                TranslateError(err), err);
       
    83         result = STATUS_FAILED;
       
    84     }
       
    85     err = (*jvmti_env)->GetClassSignature(jvmti_env, cls, &cls_sig, &generic);
       
    86     if (err != JVMTI_ERROR_NONE) {
       
    87         printf("(GetClassSignature) unexpected error: %s (%d)\n",
       
    88                TranslateError(err), err);
       
    89         result = STATUS_FAILED;
       
    90     }
       
    91     if (cls_sig != NULL &&
       
    92             strcmp(cls_sig, "Lnsk/jvmti/MethodEntry/mentry001;") == 0) {
       
    93         if (printdump == JNI_TRUE) {
       
    94             printf(">>> retrieving method entry info ...\n");
       
    95         }
       
    96         err = (*jvmti_env)->GetMethodName(jvmti_env, method,
       
    97             &entry.name, &entry.sig, &generic);
       
    98         if (err != JVMTI_ERROR_NONE) {
       
    99             printf("(GetMethodName) unexpected error: %s (%d)\n",
       
   100                    TranslateError(err), err);
       
   101             result = STATUS_FAILED;
       
   102         }
       
   103         err = (*jvmti_env)->GetFrameLocation(jvmti_env, thr, 0, &mid, &entry.loc);
       
   104         if (err != JVMTI_ERROR_NONE) {
       
   105             printf("(GetFrameLocation) unexpected error: %s (%d)\n",
       
   106                    TranslateError(err), err);
       
   107             result = STATUS_FAILED;
       
   108         }
       
   109         if (printdump == JNI_TRUE) {
       
   110             printf(">>>      class: \"%s\"\n", cls_sig);
       
   111             printf(">>>     method: \"%s%s\"\n", entry.name, entry.sig);
       
   112             printf(">>>   location: %s\n", jlong_to_string(entry.loc, buffer));
       
   113             printf(">>> ... done\n");
       
   114         }
       
   115         if (eventsCount < sizeof(entries)/sizeof(entry_info)) {
       
   116             if (entry.name == NULL ||
       
   117                     strcmp(entry.name, entries[eventsCount].name) != 0) {
       
   118                 printf("(entry#%" PRIuPTR ") wrong method name: \"%s\"",
       
   119                        eventsCount, entry.name);
       
   120                 printf(", expected: \"%s\"\n", entries[eventsCount].name);
       
   121                 result = STATUS_FAILED;
       
   122             }
       
   123             if (entry.sig == NULL ||
       
   124                     strcmp(entry.sig, entries[eventsCount].sig) != 0) {
       
   125                 printf("(entry#%" PRIuPTR ") wrong method sig: \"%s\"",
       
   126                        eventsCount, entry.sig);
       
   127                 printf(", expected: \"%s\"\n", entries[eventsCount].sig);
       
   128                 result = STATUS_FAILED;
       
   129             }
       
   130             if (entry.loc != entries[eventsCount].loc) {
       
   131                 printf("(entry#%" PRIuPTR ") wrong location: %s",
       
   132                        eventsCount, jlong_to_string(entry.loc, buffer));
       
   133                 printf(", expected: %s\n",
       
   134                        jlong_to_string(entries[eventsCount].loc, buffer));
       
   135                 result = STATUS_FAILED;
       
   136             }
       
   137         } else {
       
   138             printf("Unexpected method entry catched:");
       
   139             printf("     class: \"%s\"\n", cls_sig);
       
   140             printf("    method: \"%s%s\"\n", entry.name, entry.sig);
       
   141             printf("  location: %s\n", jlong_to_string(entry.loc, buffer));
       
   142             result = STATUS_FAILED;
       
   143         }
       
   144         eventsCount++;
       
   145     }
       
   146 }
       
   147 
       
   148 #ifdef STATIC_BUILD
       
   149 JNIEXPORT jint JNICALL Agent_OnLoad_mentry001(JavaVM *jvm, char *options, void *reserved) {
       
   150     return Agent_Initialize(jvm, options, reserved);
       
   151 }
       
   152 JNIEXPORT jint JNICALL Agent_OnAttach_mentry001(JavaVM *jvm, char *options, void *reserved) {
       
   153     return Agent_Initialize(jvm, options, reserved);
       
   154 }
       
   155 JNIEXPORT jint JNI_OnLoad_mentry001(JavaVM *jvm, char *options, void *reserved) {
       
   156     return JNI_VERSION_1_8;
       
   157 }
       
   158 #endif
       
   159 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
       
   160     jvmtiError err;
       
   161     jint res;
       
   162 
       
   163     if (options != NULL && strcmp(options, "printdump") == 0) {
       
   164         printdump = JNI_TRUE;
       
   165     }
       
   166 
       
   167     res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
       
   168         JVMTI_VERSION_1_1);
       
   169     if (res != JNI_OK || jvmti == NULL) {
       
   170         printf("Wrong result of a valid call to GetEnv!\n");
       
   171         return JNI_ERR;
       
   172     }
       
   173 
       
   174     err = (*jvmti)->GetPotentialCapabilities(jvmti, &caps);
       
   175     if (err != JVMTI_ERROR_NONE) {
       
   176         printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
       
   177                TranslateError(err), err);
       
   178         return JNI_ERR;
       
   179     }
       
   180 
       
   181     err = (*jvmti)->AddCapabilities(jvmti, &caps);
       
   182     if (err != JVMTI_ERROR_NONE) {
       
   183         printf("(AddCapabilities) unexpected error: %s (%d)\n",
       
   184                TranslateError(err), err);
       
   185         return JNI_ERR;
       
   186     }
       
   187 
       
   188     err = (*jvmti)->GetCapabilities(jvmti, &caps);
       
   189     if (err != JVMTI_ERROR_NONE) {
       
   190         printf("(GetCapabilities) unexpected error: %s (%d)\n",
       
   191                TranslateError(err), err);
       
   192         return JNI_ERR;
       
   193     }
       
   194 
       
   195     if (caps.can_generate_method_entry_events) {
       
   196         callbacks.MethodEntry = &MethodEntry;
       
   197         err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
       
   198         if (err != JVMTI_ERROR_NONE) {
       
   199             printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
       
   200                    TranslateError(err), err);
       
   201             return JNI_ERR;
       
   202         }
       
   203     } else {
       
   204         printf("Warning: MethodEntry event is not implemented\n");
       
   205     }
       
   206 
       
   207     return JNI_OK;
       
   208 }
       
   209 
       
   210 JNIEXPORT void JNICALL
       
   211 Java_nsk_jvmti_MethodEntry_mentry001_enable(JNIEnv *env, jclass cls) {
       
   212     jvmtiError err;
       
   213 
       
   214     if (jvmti == NULL) {
       
   215         return;
       
   216     }
       
   217 
       
   218     if (!caps.can_generate_method_entry_events) {
       
   219         return;
       
   220     }
       
   221 
       
   222     err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
       
   223             JVMTI_EVENT_METHOD_ENTRY, NULL);
       
   224     if (err == JVMTI_ERROR_NONE) {
       
   225         eventsExpected = sizeof(entries)/sizeof(entry_info);
       
   226     } else {
       
   227         printf("Failed to enable JVMTI_EVENT_METHOD_ENTRY event: %s (%d)\n",
       
   228                TranslateError(err), err);
       
   229         result = STATUS_FAILED;
       
   230     }
       
   231 }
       
   232 
       
   233 JNIEXPORT jint JNICALL
       
   234 Java_nsk_jvmti_MethodEntry_mentry001_check(JNIEnv *env, jclass cls) {
       
   235     jmethodID mid;
       
   236 
       
   237     mid = JNI_ENV_PTR(env)->GetStaticMethodID(JNI_ENV_ARG(env, cls),
       
   238         "dummy", "()V");
       
   239     if (mid == NULL) {
       
   240         printf("Cannot find metod \"dummy()\"!\n");
       
   241         return STATUS_FAILED;
       
   242     }
       
   243 
       
   244     JNI_ENV_PTR(env)->CallStaticVoidMethod(JNI_ENV_ARG(env, cls), mid);
       
   245     if (eventsCount != eventsExpected) {
       
   246         printf("Wrong number of MethodEntry events: %" PRIuPTR ", expected: %" PRIuPTR "\n",
       
   247             eventsCount, eventsExpected);
       
   248         result = STATUS_FAILED;
       
   249     }
       
   250     return result;
       
   251 }
       
   252 
       
   253 JNIEXPORT void JNICALL
       
   254 Java_nsk_jvmti_MethodEntry_mentry001_chain(JNIEnv *env, jclass cls) {
       
   255     jvmtiError err;
       
   256 
       
   257     if (jvmti == NULL) {
       
   258         printf("JVMTI client was not properly loaded!\n");
       
   259         result = STATUS_FAILED;
       
   260         return;
       
   261     }
       
   262 
       
   263     if (!caps.can_generate_method_entry_events) {
       
   264         return;
       
   265     }
       
   266 
       
   267     err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_DISABLE,
       
   268             JVMTI_EVENT_METHOD_ENTRY, NULL);
       
   269     if (err != JVMTI_ERROR_NONE) {
       
   270         printf("Failed to disable JVMTI_EVENT_METHOD_ENTRY event: %s (%d)\n",
       
   271                TranslateError(err), err);
       
   272         result = STATUS_FAILED;
       
   273     }
       
   274 }
       
   275 
       
   276 #ifdef __cplusplus
       
   277 }
       
   278 #endif