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 <stdio.h>
25 #include <string.h>
26 #include "jvmti.h"
27 #include "agent_common.h"
28 #include "JVMTITools.h"
29
30 extern "C" {
31
32
33 #define PASSED 0
34 #define STATUS_FAILED 2
35
36 static jvmtiEnv *jvmti = NULL;
37 static jvmtiCapabilities caps;
38 static jint result = PASSED;
39 static jboolean printdump = JNI_FALSE;
40
41 #ifdef STATIC_BUILD
Agent_OnLoad_localtab002(JavaVM * jvm,char * options,void * reserved)42 JNIEXPORT jint JNICALL Agent_OnLoad_localtab002(JavaVM *jvm, char *options, void *reserved) {
43 return Agent_Initialize(jvm, options, reserved);
44 }
Agent_OnAttach_localtab002(JavaVM * jvm,char * options,void * reserved)45 JNIEXPORT jint JNICALL Agent_OnAttach_localtab002(JavaVM *jvm, char *options, void *reserved) {
46 return Agent_Initialize(jvm, options, reserved);
47 }
JNI_OnLoad_localtab002(JavaVM * jvm,char * options,void * reserved)48 JNIEXPORT jint JNI_OnLoad_localtab002(JavaVM *jvm, char *options, void *reserved) {
49 return JNI_VERSION_1_8;
50 }
51 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)52 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
53 jint res;
54 jvmtiError err;
55
56 if (options != NULL && strcmp(options, "printdump") == 0) {
57 printdump = JNI_TRUE;
58 }
59
60 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
61 if (res != JNI_OK || jvmti == NULL) {
62 printf("Wrong result of a valid call to GetEnv!\n");
63 return JNI_ERR;
64 }
65
66 err = jvmti->GetPotentialCapabilities(&caps);
67 if (err != JVMTI_ERROR_NONE) {
68 printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
69 TranslateError(err), err);
70 return JNI_ERR;
71 }
72
73 err = jvmti->AddCapabilities(&caps);
74 if (err != JVMTI_ERROR_NONE) {
75 printf("(AddCapabilities) unexpected error: %s (%d)\n",
76 TranslateError(err), err);
77 return JNI_ERR;
78 }
79
80 err = jvmti->GetCapabilities(&caps);
81 if (err != JVMTI_ERROR_NONE) {
82 printf("(GetCapabilities) unexpected error: %s (%d)\n",
83 TranslateError(err), err);
84 return JNI_ERR;
85 }
86
87 if (!caps.can_access_local_variables) {
88 printf("Warning: Access to local variables is not implemented\n");
89 }
90
91 return JNI_OK;
92 }
93
94 JNIEXPORT jint JNICALL
Java_nsk_jvmti_GetLocalVariableTable_localtab002_check(JNIEnv * env,jclass cls)95 Java_nsk_jvmti_GetLocalVariableTable_localtab002_check(JNIEnv *env, jclass cls) {
96 jvmtiError err;
97 jmethodID mid;
98 jint entryCount;
99 jvmtiLocalVariableEntry *table;
100
101 if (jvmti == NULL) {
102 printf("JVMTI client was not properly loaded!\n");
103 return STATUS_FAILED;
104 }
105
106 if (!caps.can_access_local_variables) return result;
107
108 mid = env->GetMethodID(cls, "<init>", "()V");
109 if (mid == NULL) {
110 printf("Cannot get method ID for \"<init>\"!\n");
111 return STATUS_FAILED;
112 }
113
114 if (printdump == JNI_TRUE) {
115 printf(">>> invalid method check ...\n");
116 }
117 err = jvmti->GetLocalVariableTable(NULL, &entryCount, &table);
118 if (err != JVMTI_ERROR_INVALID_METHODID) {
119 printf("Error expected: JVMTI_ERROR_INVALID_METHODID,\n");
120 printf("\tactual: %s (%d)\n", TranslateError(err), err);
121 result = STATUS_FAILED;
122 }
123
124 if (printdump == JNI_TRUE) {
125 printf(">>> (entryCountPtr) null pointer check ...\n");
126 }
127 err = jvmti->GetLocalVariableTable(mid, NULL, &table);
128 if (err != JVMTI_ERROR_NULL_POINTER) {
129 printf("Error expected: JVMTI_ERROR_NULL_POINTER,\n");
130 printf("\tactual: %s (%d)\n", TranslateError(err), err);
131 result = STATUS_FAILED;
132 }
133
134 if (printdump == JNI_TRUE) {
135 printf(">>> (tablePtr) null pointer check ...\n");
136 }
137 err = jvmti->GetLocalVariableTable(mid, &entryCount, NULL);
138 if (err != JVMTI_ERROR_NULL_POINTER) {
139 printf("Error expected: JVMTI_ERROR_NULL_POINTER,\n");
140 printf("\tactual: %s (%d)\n", TranslateError(err), err);
141 result = STATUS_FAILED;
142 }
143
144 mid = env->GetStaticMethodID(cls, "check", "()I");
145 if (mid == NULL) {
146 printf("Cannot get method ID for \"check\"!\n");
147 return STATUS_FAILED;
148 }
149
150 if (printdump == JNI_TRUE) {
151 printf(">>> native method check ...\n");
152 }
153 err = jvmti->GetLocalVariableTable(mid, &entryCount, &table);
154 if (err != JVMTI_ERROR_NATIVE_METHOD) {
155 printf("Error expected: JVMTI_ERROR_NATIVE_METHOD,\n");
156 printf("\tactual: %s (%d)\n", TranslateError(err), err);
157 result = STATUS_FAILED;
158 }
159
160 if (printdump == JNI_TRUE) {
161 printf(">>> ... done\n");
162 }
163
164 return result;
165 }
166
167 }
168