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 <stdlib.h>
25 #include <string.h>
26 #include "jvmti.h"
27 #include "agent_common.h"
28 #include "jni_tools.h"
29 #include "jvmti_tools.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /* ============================================================================= */
36 
37 static jlong timeout = 0;
38 
39 #define STATUS_FAIL     97
40 
41 #define EVENTS_COUNT    2
42 
43 static jvmtiEvent events[EVENTS_COUNT] = {
44     JVMTI_EVENT_VM_INIT,
45     JVMTI_EVENT_VM_DEATH
46 };
47 
48 static jvmtiCapabilities initCaps;
49 
50 /* ============================================================================= */
51 
52 /** Prints capabilities structure as raw bits. */
printRawCapabilities(const jvmtiCapabilities * caps)53 static void printRawCapabilities(const jvmtiCapabilities* caps) {
54     const unsigned char* p = (const unsigned char*)caps;
55     int size = (int) sizeof(jvmtiCapabilities);
56     int i, j, k;
57 
58     nsk_printf("            ");
59     for (j = 0; j < 16; j++) {
60         nsk_printf(" %1X", j);
61     }
62     nsk_printf("\n");
63 
64     for (i = 0; i < size; i += 2) {
65         int prefix = i / 2;
66 
67         nsk_printf("    0x%03X.: ", prefix);
68         for (k = 0; k < 2; k++) {
69             unsigned char b = *(p++);
70 
71             for (j = 0; j < 8; j++) {
72                 int bit = b % 2;
73                 b /= 2;
74                 nsk_printf(" %1d", bit);
75             }
76         }
77         nsk_printf("\n");
78     }
79 }
80 
81 #define PRINT_CAP(caps, name)  nsk_printf("    %-40s: %d\n", #name, (int)caps->name)
82 
83 /** Print values of known capabilities. */
printKnownCapabilities(const jvmtiCapabilities * caps)84 static void printKnownCapabilities(const jvmtiCapabilities* caps) {
85     PRINT_CAP(caps, can_tag_objects);
86     PRINT_CAP(caps, can_generate_field_modification_events);
87     PRINT_CAP(caps, can_generate_field_access_events);
88     PRINT_CAP(caps, can_get_bytecodes);
89     PRINT_CAP(caps, can_get_synthetic_attribute);
90     PRINT_CAP(caps, can_get_owned_monitor_info);
91     PRINT_CAP(caps, can_get_current_contended_monitor);
92     PRINT_CAP(caps, can_get_monitor_info);
93     PRINT_CAP(caps, can_pop_frame);
94     PRINT_CAP(caps, can_redefine_classes);
95     PRINT_CAP(caps, can_signal_thread);
96     PRINT_CAP(caps, can_get_source_file_name);
97     PRINT_CAP(caps, can_get_line_numbers);
98     PRINT_CAP(caps, can_get_source_debug_extension);
99     PRINT_CAP(caps, can_access_local_variables);
100     PRINT_CAP(caps, can_maintain_original_method_order);
101     PRINT_CAP(caps, can_generate_single_step_events);
102     PRINT_CAP(caps, can_generate_exception_events);
103     PRINT_CAP(caps, can_generate_frame_pop_events);
104     PRINT_CAP(caps, can_generate_breakpoint_events);
105     PRINT_CAP(caps, can_suspend);
106     /* :1 */
107     PRINT_CAP(caps, can_get_current_thread_cpu_time);
108     PRINT_CAP(caps, can_get_thread_cpu_time);
109     PRINT_CAP(caps, can_generate_method_entry_events);
110     PRINT_CAP(caps, can_generate_method_exit_events);
111     PRINT_CAP(caps, can_generate_all_class_hook_events);
112     PRINT_CAP(caps, can_generate_compiled_method_load_events);
113     PRINT_CAP(caps, can_generate_monitor_events);
114     PRINT_CAP(caps, can_generate_vm_object_alloc_events);
115     PRINT_CAP(caps, can_generate_native_method_bind_events);
116     PRINT_CAP(caps, can_generate_garbage_collection_events);
117     PRINT_CAP(caps, can_generate_object_free_events);
118     /* :15 */
119     /* :16 */
120     /* :16 */
121     /* :16 */
122     /* :16 */
123     /* :16 */
124 }
125 
126 #define CHECK_CAP(initCaps, caps, name)                                         \
127     if (initCaps->name != caps->name) {                                         \
128         success = NSK_FALSE;                                                    \
129         NSK_COMPLAIN4("GetCapabilities() in %s returned after adding empty capabilities list:"  \
130                       "#   capability: %s\n"                                    \
131                       "#   got value:  %d\n"                                    \
132                       "#   expected:   %d\n",                                   \
133                         where, #name, (int)caps->name, initCaps->name);               \
134     }
135 
136 /**
137  * Check value of known capabilities.
138  * @returns NSK_FALSE if any error occured.
139  */
checkCapabilitiesValue(jvmtiCapabilities * caps,jvmtiCapabilities * initCaps,const char where[])140 static int checkCapabilitiesValue(jvmtiCapabilities* caps, jvmtiCapabilities* initCaps, const char where[]) {
141     int success = NSK_TRUE;
142 
143     CHECK_CAP(initCaps, caps, can_tag_objects);
144     CHECK_CAP(initCaps, caps, can_generate_field_modification_events);
145     CHECK_CAP(initCaps, caps, can_generate_field_access_events);
146     CHECK_CAP(initCaps, caps, can_get_bytecodes);
147     CHECK_CAP(initCaps, caps, can_get_synthetic_attribute);
148     CHECK_CAP(initCaps, caps, can_get_owned_monitor_info);
149     CHECK_CAP(initCaps, caps, can_get_current_contended_monitor);
150     CHECK_CAP(initCaps, caps, can_get_monitor_info);
151     CHECK_CAP(initCaps, caps, can_pop_frame);
152     CHECK_CAP(initCaps, caps, can_redefine_classes);
153     CHECK_CAP(initCaps, caps, can_signal_thread);
154     CHECK_CAP(initCaps, caps, can_get_source_file_name);
155     CHECK_CAP(initCaps, caps, can_get_line_numbers);
156     CHECK_CAP(initCaps, caps, can_get_source_debug_extension);
157     CHECK_CAP(initCaps, caps, can_access_local_variables);
158     CHECK_CAP(initCaps, caps, can_maintain_original_method_order);
159     CHECK_CAP(initCaps, caps, can_generate_single_step_events);
160     CHECK_CAP(initCaps, caps, can_generate_exception_events);
161     CHECK_CAP(initCaps, caps, can_generate_frame_pop_events);
162     CHECK_CAP(initCaps, caps, can_generate_breakpoint_events);
163     CHECK_CAP(initCaps, caps, can_suspend);
164     /* :1 */
165     CHECK_CAP(initCaps, caps, can_get_current_thread_cpu_time);
166     CHECK_CAP(initCaps, caps, can_get_thread_cpu_time);
167     CHECK_CAP(initCaps, caps, can_generate_method_entry_events);
168     CHECK_CAP(initCaps, caps, can_generate_method_exit_events);
169     CHECK_CAP(initCaps, caps, can_generate_all_class_hook_events);
170     CHECK_CAP(initCaps, caps, can_generate_compiled_method_load_events);
171     CHECK_CAP(initCaps, caps, can_generate_monitor_events);
172     CHECK_CAP(initCaps, caps, can_generate_vm_object_alloc_events);
173     CHECK_CAP(initCaps, caps, can_generate_native_method_bind_events);
174     CHECK_CAP(initCaps, caps, can_generate_garbage_collection_events);
175     CHECK_CAP(initCaps, caps, can_generate_object_free_events);
176     /* :15 */
177     /* :16 */
178     /* :16 */
179     /* :16 */
180     /* :16 */
181     /* :16 */
182 
183     return success;
184 }
185 
186 /**
187  * Get and check current capabilities.
188  * @returns NSK_FALSE if any error occured.
189  */
checkCapabilities(jvmtiEnv * jvmti,jvmtiCapabilities * initCaps,const char where[])190 static int checkCapabilities(jvmtiEnv* jvmti, jvmtiCapabilities* initCaps, const char where[]) {
191     int success = NSK_TRUE;
192     jvmtiCapabilities caps;
193 
194     memset(&caps, 0, sizeof(jvmtiCapabilities));
195 
196     NSK_DISPLAY0("GetCapabilities() for current JVMTI env\n");
197     if (!NSK_JVMTI_VERIFY(
198             NSK_CPP_STUB2(GetCapabilities, jvmti, &caps))) {
199         return NSK_FALSE;
200     }
201 
202     NSK_DISPLAY0("Got raw capabilities:\n");
203     printRawCapabilities(&caps);
204 
205     NSK_DISPLAY0("Known capabilities:\n");
206     printKnownCapabilities(&caps);
207 
208     NSK_DISPLAY0("Checking capabilities value:\n");
209     success = checkCapabilitiesValue(&caps, initCaps, where);
210     NSK_DISPLAY0("  ... checked\n");
211 
212     return success;
213 }
214 
215 /**
216  * Add given capabilities list.
217  * @returns NSK_FALSE if any error occured.
218  */
addCapabilities(jvmtiEnv * jvmti,jvmtiCapabilities * caps,const char where[])219 static int addCapabilities(jvmtiEnv* jvmti, jvmtiCapabilities* caps, const char where[]) {
220     NSK_DISPLAY0("AddCapabilities() for current JVMTI env\n");
221     if (!NSK_JVMTI_VERIFY(
222             NSK_CPP_STUB2(AddCapabilities, jvmti, caps))) {
223         return NSK_FALSE;
224     }
225     NSK_DISPLAY0("  ... set\n");
226 
227     return NSK_TRUE;
228 }
229 
230 /* ============================================================================= */
231 
232 /** Agent algorithm. */
233 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * jni,void * arg)234 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
235     NSK_DISPLAY0("Wait for debugee to become ready\n");
236     if (!nsk_jvmti_waitForSync(timeout))
237         return;
238 
239     NSK_DISPLAY0(">>> Testcase #3: Check capabilities in agent thread\n");
240     if (!checkCapabilities(jvmti, &initCaps, "agent thread")) {
241         nsk_jvmti_setFailStatus();
242     }
243 
244     NSK_DISPLAY0("Let debugee to finish\n");
245     if (!nsk_jvmti_resumeSync())
246         return;
247 }
248 
249 /* ============================================================================= */
250 
251 /**
252  * Callback for VM_INIT event.
253  */
254 JNIEXPORT void JNICALL
callbackVMInit(jvmtiEnv * jvmti,JNIEnv * jni,jthread thread)255 callbackVMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) {
256 
257     NSK_DISPLAY0(">>> Testcase #2: Check capabilities in VM_INIT callback\n");
258     if (!checkCapabilities(jvmti, &initCaps, "VM_INIT callback")) {
259         nsk_jvmti_setFailStatus();
260     }
261 
262 }
263 
264 /**
265  * Callback for VM_DEATH event.
266  */
267 JNIEXPORT void JNICALL
callbackVMDeath(jvmtiEnv * jvmti,JNIEnv * jni)268 callbackVMDeath(jvmtiEnv* jvmti, JNIEnv* jni) {
269     int success = NSK_TRUE;
270 
271     NSK_DISPLAY0(">>> Testcase #4: Check capabilities in VM_DEATH callback\n");
272     success = checkCapabilities(jvmti, &initCaps, "VM_DEATH callback");
273 
274     NSK_DISPLAY1("Disable events: %d events\n", EVENTS_COUNT);
275     if (!nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, events, NULL)) {
276         success = NSK_FALSE;
277     } else {
278         NSK_DISPLAY0("  ... disabled\n");
279     }
280 
281     if (!success) {
282         NSK_DISPLAY1("Exit with FAIL exit status: %d\n", STATUS_FAIL);
283         NSK_BEFORE_TRACE(exit(STATUS_FAIL));
284     }
285 }
286 
287 /* ============================================================================= */
288 
289 /** Agent library initialization. */
290 #ifdef STATIC_BUILD
Agent_OnLoad_addcaps001(JavaVM * jvm,char * options,void * reserved)291 JNIEXPORT jint JNICALL Agent_OnLoad_addcaps001(JavaVM *jvm, char *options, void *reserved) {
292     return Agent_Initialize(jvm, options, reserved);
293 }
Agent_OnAttach_addcaps001(JavaVM * jvm,char * options,void * reserved)294 JNIEXPORT jint JNICALL Agent_OnAttach_addcaps001(JavaVM *jvm, char *options, void *reserved) {
295     return Agent_Initialize(jvm, options, reserved);
296 }
JNI_OnLoad_addcaps001(JavaVM * jvm,char * options,void * reserved)297 JNIEXPORT jint JNI_OnLoad_addcaps001(JavaVM *jvm, char *options, void *reserved) {
298     return JNI_VERSION_1_8;
299 }
300 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)301 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
302     jvmtiEnv* jvmti = NULL;
303 
304     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
305         return JNI_ERR;
306 
307     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
308 
309     if (!NSK_VERIFY((jvmti =
310             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
311         return JNI_ERR;
312 
313     {
314         jvmtiEventCallbacks eventCallbacks;
315 
316         memset(&eventCallbacks, 0, sizeof(eventCallbacks));
317         eventCallbacks.VMInit = callbackVMInit;
318         eventCallbacks.VMDeath = callbackVMDeath;
319         if (!NSK_JVMTI_VERIFY(
320                 NSK_CPP_STUB3(SetEventCallbacks, jvmti,
321                                     &eventCallbacks, sizeof(eventCallbacks)))) {
322             return JNI_ERR;
323         }
324 
325     }
326 
327     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
328         return JNI_ERR;
329 
330     NSK_DISPLAY0(">>> Testcase #0: Add empty capabilities list in Agent_OnLoad()\n");
331     memset(&initCaps, 0, sizeof(jvmtiCapabilities));
332     if (!addCapabilities(jvmti, &initCaps, "Agent_OnLoad()")) {
333         nsk_jvmti_setFailStatus();
334     }
335 
336     NSK_DISPLAY0(">>> Testcase #1: Check capabilities in Agent_OnLoad()\n");
337     if (!checkCapabilities(jvmti, &initCaps, "Agent_OnLoad()")) {
338         nsk_jvmti_setFailStatus();
339     }
340 
341     NSK_DISPLAY1("Enable events: %d events\n", EVENTS_COUNT);
342     if (nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT, events, NULL)) {
343         NSK_DISPLAY0("  ... enabled\n");
344     }
345 
346     return JNI_OK;
347 }
348 
349 /* ============================================================================= */
350 
351 #ifdef __cplusplus
352 }
353 #endif
354