test/hotspot/jtreg/serviceability/jvmti/NotifyFramePop/libNotifyFramePopTest.c
changeset 50385 50bfe66c499f
equal deleted inserted replaced
50382:ce5352719340 50385:50bfe66c499f
       
     1 /*
       
     2  * Copyright (c) 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 <stdio.h>
       
    25 #include <string.h>
       
    26 #include "jvmti.h"
       
    27 
       
    28 #ifdef __cplusplus
       
    29 extern "C" {
       
    30 #endif
       
    31 
       
    32 #ifndef JNI_ENV_ARG
       
    33 
       
    34 #ifdef __cplusplus
       
    35 #define JNI_ENV_ARG(x, y) y
       
    36 #define JNI_ENV_PTR(x) x
       
    37 #else
       
    38 #define JNI_ENV_ARG(x,y) x, y
       
    39 #define JNI_ENV_PTR(x) (*x)
       
    40 #endif
       
    41 
       
    42 #endif
       
    43 
       
    44 static jvmtiEnv *jvmti = NULL;
       
    45 static jvmtiCapabilities caps;
       
    46 static jvmtiEventCallbacks callbacks;
       
    47 static jboolean framePopReceived = JNI_FALSE;
       
    48 
       
    49 static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
       
    50 
       
    51 JNIEXPORT
       
    52 jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
       
    53     return Agent_Initialize(jvm, options, reserved);
       
    54 }
       
    55 
       
    56 JNIEXPORT
       
    57 jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
       
    58     return Agent_Initialize(jvm, options, reserved);
       
    59 }
       
    60 
       
    61 JNIEXPORT
       
    62 jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
       
    63     return JNI_VERSION_9;
       
    64 }
       
    65 
       
    66 
       
    67 static void reportError(const char *msg, int err) {
       
    68     fprintf(stdout, "%s, error: %d\n", msg, err);
       
    69     fflush(stdout);
       
    70 }
       
    71 
       
    72 
       
    73 static void JNICALL
       
    74 FramePop(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread,
       
    75          jmethodID method, jboolean wasPoppedByException)
       
    76 {
       
    77     jvmtiError err;
       
    78     jclass cls = NULL;
       
    79     char* csig = NULL;
       
    80     char* name = NULL;
       
    81     char* sign = NULL;
       
    82 
       
    83     framePopReceived = JNI_TRUE;
       
    84 
       
    85     err = (*jvmti_env)->GetMethodDeclaringClass(jvmti_env, method, &cls);
       
    86     if (err != JVMTI_ERROR_NONE) {
       
    87         reportError("FramePop: GetMethodDeclaringClass failed", err);
       
    88     }
       
    89     err = (*jvmti_env)->GetClassSignature(jvmti_env, cls, &csig, NULL);
       
    90     if (err != JVMTI_ERROR_NONE) {
       
    91         reportError("FramePop: GetClassSignature failed", err);
       
    92     }
       
    93     err = (*jvmti_env)->GetMethodName(jvmti_env, method, &name, &sign, NULL);
       
    94     if (err != JVMTI_ERROR_NONE) {
       
    95         reportError("FramePop: GetMethodName failed", err);
       
    96     }
       
    97     fprintf(stdout, "FramePop event from method: %s %s%s\n", csig, name, sign);
       
    98     fflush(stdout);
       
    99 
       
   100     (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)csig);
       
   101     (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)name);
       
   102     (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)sign);
       
   103 }
       
   104 
       
   105 static
       
   106 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
       
   107     jint res;
       
   108     jvmtiError err;
       
   109 
       
   110     res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_9);
       
   111     if (res != JNI_OK || jvmti == NULL) {
       
   112         reportError("GetEnv(JVMTI_VERSION_9) failed", res);
       
   113         return JNI_ERR;
       
   114     }
       
   115     err = (*jvmti)->GetPotentialCapabilities(jvmti, &caps);
       
   116     if (err != JVMTI_ERROR_NONE) {
       
   117         reportError("GetPotentialCapabilities failed", err);
       
   118         return JNI_ERR;
       
   119     }
       
   120     err = (*jvmti)->AddCapabilities(jvmti, &caps);
       
   121     if (err != JVMTI_ERROR_NONE) {
       
   122         reportError("AddCapabilities failed",err);
       
   123         return JNI_ERR;
       
   124     }
       
   125     err = (*jvmti)->GetCapabilities(jvmti, &caps);
       
   126     if (err != JVMTI_ERROR_NONE) {
       
   127         reportError("GetCapabilities failed", err);
       
   128         return JNI_ERR;
       
   129     }
       
   130     if (caps.can_generate_frame_pop_events) {
       
   131         callbacks.FramePop = &FramePop;
       
   132         err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
       
   133         if (err != JVMTI_ERROR_NONE) {
       
   134             reportError("SetEventCallbacks failed", err);
       
   135             return JNI_ERR;
       
   136         }
       
   137     }
       
   138     return JNI_OK;
       
   139 }
       
   140 
       
   141 JNIEXPORT jboolean JNICALL
       
   142 Java_NotifyFramePopTest_canGenerateFramePopEvents(JNIEnv *env, jclass cls) {
       
   143     return caps.can_generate_frame_pop_events ? JNI_TRUE : JNI_FALSE;
       
   144 }
       
   145 
       
   146 JNIEXPORT void JNICALL
       
   147 Java_NotifyFramePopTest_setFramePopNotificationMode(JNIEnv *env, jclass cl, jboolean enable) {
       
   148     jvmtiEventMode mode = enable ? JVMTI_ENABLE : JVMTI_DISABLE;
       
   149     jvmtiError err = (*jvmti)->SetEventNotificationMode(jvmti, mode, JVMTI_EVENT_FRAME_POP, NULL);
       
   150     if (err != JVMTI_ERROR_NONE) {
       
   151         reportError("Failed to set notification mode for FRAME_POP events", err);
       
   152     }
       
   153 }
       
   154 
       
   155 JNIEXPORT void JNICALL
       
   156 Java_NotifyFramePopTest_notifyFramePop(JNIEnv *env, jclass cls, jthread thread)
       
   157 {
       
   158     jvmtiError err= (*jvmti)->NotifyFramePop(jvmti, thread, 1);
       
   159     if (err != JVMTI_ERROR_NONE) {
       
   160         reportError("NotifyFramePop failed", err);
       
   161     }
       
   162 }
       
   163 
       
   164 JNIEXPORT jboolean JNICALL
       
   165 Java_NotifyFramePopTest_framePopReceived(JNIEnv *env, jclass cls) {
       
   166     jboolean result = framePopReceived;
       
   167     framePopReceived = JNI_FALSE;
       
   168     return result;
       
   169 }
       
   170 
       
   171 #ifdef __cplusplus
       
   172 }
       
   173 #endif