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