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