test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS202/hs202t002/hs202t002.c
changeset 50260 46c67f5e27c2
equal deleted inserted replaced
50259:01d27ae7a84e 50260:46c67f5e27c2
       
     1 /*
       
     2  * Copyright (c) 2007, 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 #include <jni.h>
       
    24 #include <jvmti.h>
       
    25 #include "agent_common.h"
       
    26 #include <string.h>
       
    27 #include <stdarg.h>
       
    28 #include "jvmti_tools.h"
       
    29 #include "JVMTITools.h"
       
    30 
       
    31 /*
       
    32 hs202t002:
       
    33 */
       
    34 #ifdef __cplusplus
       
    35 extern "C" {
       
    36 #endif
       
    37 
       
    38 #define FILE_NAME "nsk/jvmti/scenarios/hotswap/HS202/hs202t002/MyThread"
       
    39 #define CLASS_NAME "Lnsk/jvmti/scenarios/hotswap/HS202/hs202t002/MyThread;"
       
    40 
       
    41 #define PATH_FORMAT "%s%02d/%s"
       
    42 #define DIR_NAME "newclass"
       
    43 #define METHOD_NAME "display"
       
    44 
       
    45 static jint redefineNumber = 0;
       
    46 static jvmtiEnv * jvmti = NULL;
       
    47 
       
    48 typedef enum {
       
    49   suspend_error = -1,
       
    50   not_suspended,
       
    51   suspended
       
    52 } thread_suspend_status_t;
       
    53 
       
    54 static volatile thread_suspend_status_t thread_suspend_status = not_suspended;
       
    55 
       
    56 void JNICALL callbackMethodExit(jvmtiEnv *jvmti_env,
       
    57                                 JNIEnv* jni_env,
       
    58                                 jthread thread,
       
    59                                 jmethodID method,
       
    60                                 jboolean was_popped_by_exception,
       
    61                                 jvalue return_value) {
       
    62     if ( was_popped_by_exception ) {
       
    63         char * name;
       
    64         char * signature;
       
    65         char * generic ;
       
    66         jvmtiError err;
       
    67         err= JVMTI_ERROR_NONE;
       
    68         (*jvmti_env)->GetMethodName(jvmti_env, method, &name, &signature, &generic);
       
    69         if (strcmp(name,METHOD_NAME) == 0) {
       
    70             jclass cls;
       
    71             char fileName[512];
       
    72             nsk_jvmti_getFileName(redefineNumber, FILE_NAME, fileName,
       
    73                                   sizeof(fileName)/sizeof(char));
       
    74             (*jvmti_env)->GetMethodDeclaringClass(jvmti_env,method, &cls);
       
    75             if ( nsk_jvmti_redefineClass(jvmti_env, cls,fileName) == NSK_TRUE ) {
       
    76                 nsk_printf(" Agent:: redefine class success ..\n");
       
    77                 nsk_printf("Agent::SUSPENDING>> \n");
       
    78                 err=(*jvmti_env)->SuspendThread(jvmti_env,thread);
       
    79                 if (err ==  JVMTI_ERROR_NONE) {
       
    80                     thread_suspend_status = suspended;
       
    81                     nsk_printf("Agent:: Thread successfully suspended..\n");
       
    82                 } else if (err == JVMTI_ERROR_THREAD_SUSPENDED) {
       
    83                     thread_suspend_status = suspend_error;
       
    84                     nsk_printf(" ## Error occured %s \n",TranslateError(err));
       
    85                 }
       
    86             }
       
    87         }
       
    88     }
       
    89 }
       
    90 
       
    91 #ifdef STATIC_BUILD
       
    92 JNIEXPORT jint JNICALL Agent_OnLoad_hs202t002(JavaVM *jvm, char *options, void *reserved) {
       
    93     return Agent_Initialize(jvm, options, reserved);
       
    94 }
       
    95 JNIEXPORT jint JNICALL Agent_OnAttach_hs202t002(JavaVM *jvm, char *options, void *reserved) {
       
    96     return Agent_Initialize(jvm, options, reserved);
       
    97 }
       
    98 JNIEXPORT jint JNI_OnLoad_hs202t002(JavaVM *jvm, char *options, void *reserved) {
       
    99     return JNI_VERSION_1_8;
       
   100 }
       
   101 #endif
       
   102 jint  Agent_Initialize(JavaVM *vm, char *options, void *reserved) {
       
   103     jint rc ;
       
   104     nsk_printf("Agent:: VM.. Started..\n");
       
   105     redefineNumber=0;
       
   106     rc=(*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_1);
       
   107     if ( rc!= JNI_OK ) {
       
   108         nsk_printf("Agent:: Could not load JVMTI interface \n");
       
   109         return JNI_ERR;
       
   110     } else {
       
   111         jvmtiCapabilities caps;
       
   112         jvmtiEventCallbacks eventCallbacks;
       
   113         memset(&caps, 0, sizeof(caps));
       
   114         if (nsk_jvmti_parseOptions(options) == NSK_FALSE ) {
       
   115             nsk_printf("# error agent Failed to parse options \n");
       
   116             return JNI_ERR;
       
   117         }
       
   118         caps.can_redefine_classes = 1;
       
   119         caps.can_suspend = 1;
       
   120         caps.can_pop_frame = 1;
       
   121         caps.can_generate_method_exit_events = 1;
       
   122         (*jvmti)->AddCapabilities(jvmti, &caps);
       
   123         memset(&eventCallbacks, 0, sizeof(eventCallbacks));
       
   124         eventCallbacks.MethodExit = callbackMethodExit;
       
   125         rc=(*jvmti)->SetEventCallbacks(jvmti,&eventCallbacks, sizeof(eventCallbacks));
       
   126         if (rc != JVMTI_ERROR_NONE) {
       
   127             nsk_printf(" Agent:: Error occured while setting event callbacks \n");
       
   128             return JNI_ERR;
       
   129         }
       
   130         if (NSK_TRUE == nsk_jvmti_enableNotification(jvmti,JVMTI_EVENT_METHOD_EXIT, NULL)) {
       
   131             nsk_printf(" Agent :: NOTIFICATIONS ARE ENABLED \n");
       
   132         } else {
       
   133             nsk_printf(" Agent :: Error Enabling Notifications..");
       
   134         }
       
   135     }
       
   136     return JNI_OK;
       
   137 }
       
   138 
       
   139 JNIEXPORT jboolean JNICALL
       
   140 Java_nsk_jvmti_scenarios_hotswap_HS202_hs202t002_hs202t002_popThreadFrame(JNIEnv * jni,
       
   141                                                                           jclass clas,
       
   142                                                                           jthread thread) {
       
   143     jvmtiError err = JVMTI_ERROR_NONE;
       
   144     jboolean retvalue = JNI_FALSE;
       
   145     jint state;
       
   146     nsk_printf("Agent:: POPPING THE FRAME..\n");
       
   147     (*jvmti)->GetThreadState(jvmti, thread, &state);
       
   148     if ( state & JVMTI_THREAD_STATE_SUSPENDED) {
       
   149         err = (*jvmti)->PopFrame(jvmti,thread);
       
   150         if (err == JVMTI_ERROR_NONE) {
       
   151             nsk_printf("Agent:: PopFrame succeeded..\n");
       
   152             return JNI_TRUE;
       
   153         } else  {
       
   154             nsk_printf(" ## Error occured %s \n",TranslateError(err));
       
   155         }
       
   156     } else {
       
   157         nsk_printf("Agent:: Thread was not suspened.. check for capabilities, and java method signature ");
       
   158     }
       
   159     return retvalue;
       
   160 }
       
   161 
       
   162 JNIEXPORT jboolean JNICALL
       
   163 Java_nsk_jvmti_scenarios_hotswap_HS202_hs202t002_hs202t002_resumeThread(JNIEnv * jni,
       
   164                                                                         jclass clas,
       
   165                                                                         jthread thread) {
       
   166     jvmtiError err = JVMTI_ERROR_NONE;
       
   167     jboolean retvalue = JNI_FALSE;
       
   168 
       
   169     // disable notifications before resuming thread
       
   170     // to avoid recursion on PopFrame issued reinvoke
       
   171     if (NSK_TRUE == nsk_jvmti_disableNotification(jvmti,JVMTI_EVENT_METHOD_EXIT, NULL)) {
       
   172         nsk_printf("Agent :: nsk_jvmti_disabled notifications..\n");
       
   173     } else {
       
   174         nsk_printf("Agent :: Failed to disable notifications..");
       
   175         return JNI_FALSE;
       
   176     }
       
   177 
       
   178     err = (*jvmti)->ResumeThread(jvmti,thread);
       
   179     if (err == JVMTI_ERROR_NONE) {
       
   180         thread_suspend_status = not_suspended;
       
   181         retvalue = JNI_TRUE;
       
   182         nsk_printf(" Agent:: Thread Resumed.. \n");
       
   183     } else {
       
   184         nsk_printf(" Agent:: Failed.. to Resume the thread.\n");
       
   185         retvalue = JNI_FALSE;
       
   186     }
       
   187     return retvalue;
       
   188 }
       
   189 
       
   190 JNIEXPORT jboolean JNICALL
       
   191 Java_nsk_jvmti_scenarios_hotswap_HS202_hs202t002_hs202t002_isThreadSuspended(JNIEnv* jni,
       
   192                                                                              jclass clas,
       
   193                                                                              jthread thread) {
       
   194     if (suspend_error == thread_suspend_status) {
       
   195         jclass ex_class = (*jni)->FindClass(jni, "java/lang/IllegalThreadStateException");
       
   196         (*jni)->ThrowNew(jni, ex_class, "Thread has failed to self suspend");
       
   197         return JNI_FALSE;
       
   198     }
       
   199 
       
   200     return suspended == thread_suspend_status;
       
   201 }
       
   202 
       
   203 #ifdef __cplusplus
       
   204 }
       
   205 #endif