blob: 43a1d8319f7b366e13a5cf9f4e456e4300df0244 [file] [log] [blame]
Alex Light49948e92016-08-11 15:35:28 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "901-hello-ti-agent/basics.h"
18
Igor Murashkin5573c372017-11-16 13:34:30 -080019#include <thread>
Alex Light1edc8cf2017-03-24 14:22:56 -070020
Alex Light49948e92016-08-11 15:35:28 -070021#include <jni.h>
22#include <stdio.h>
23#include <string.h>
Andreas Gampe027444b2017-03-31 12:49:07 -070024#include "android-base/macros.h"
Andreas Gampe5e03a302017-03-13 13:10:00 -070025#include "jvmti.h"
Alex Light49948e92016-08-11 15:35:28 -070026
Andreas Gampe3f46c962017-03-30 10:26:59 -070027// Test infrastructure
28#include "jvmti_helper.h"
29#include "test_env.h"
Andreas Gampef37e3022017-01-13 17:54:46 -080030
Alex Light49948e92016-08-11 15:35:28 -070031namespace art {
32namespace Test901HelloTi {
33
Andreas Gampe3a7eb142017-01-19 21:59:22 -080034static void EnableEvent(jvmtiEnv* env, jvmtiEvent evt) {
35 jvmtiError error = env->SetEventNotificationMode(JVMTI_ENABLE, evt, nullptr);
36 if (error != JVMTI_ERROR_NONE) {
37 printf("Failed to enable event");
38 }
39}
40
Alex Lightbf9e5162017-08-16 16:07:37 -070041static jvmtiPhase getPhase(jvmtiEnv* jenv) {
42 jvmtiPhase out = static_cast<jvmtiPhase>(-1);
43 jenv->GetPhase(&out);
44 return out;
Andreas Gampe3a7eb142017-01-19 21:59:22 -080045}
46
Alex Lightbf9e5162017-08-16 16:07:37 -070047static void JNICALL VMStartCallback(jvmtiEnv *jenv, JNIEnv* jni_env ATTRIBUTE_UNUSED) {
48 printf("VMStart (phase %d)\n", getPhase(jenv));
49 fsync(1);
50}
51
52static void JNICALL VMInitCallback(jvmtiEnv *jvmti_env,
Andreas Gampe3a7eb142017-01-19 21:59:22 -080053 JNIEnv* jni_env ATTRIBUTE_UNUSED,
54 jthread thread ATTRIBUTE_UNUSED) {
Alex Lightbf9e5162017-08-16 16:07:37 -070055 printf("VMInit (phase %d)\n", getPhase(jvmti_env));
56 fsync(1);
Andreas Gampe3a7eb142017-01-19 21:59:22 -080057}
58
Alex Lightb6f34642018-01-04 11:01:48 -080059static void JNICALL VMDeathCallback(jvmtiEnv *jenv, JNIEnv* jni_env) {
Alex Lightbf9e5162017-08-16 16:07:37 -070060 printf("VMDeath (phase %d)\n", getPhase(jenv));
61 fsync(1);
Alex Lightb6f34642018-01-04 11:01:48 -080062 jthread cur_thr;
63 CHECK_EQ(jenv->GetCurrentThread(&cur_thr), JVMTI_ERROR_NONE);
64 CHECK(cur_thr != nullptr);
65 jni_env->DeleteLocalRef(cur_thr);
Andreas Gampe3a7eb142017-01-19 21:59:22 -080066}
67
68
69static void InstallVMEvents(jvmtiEnv* env) {
70 jvmtiEventCallbacks callbacks;
71 memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
72 callbacks.VMStart = VMStartCallback;
73 callbacks.VMInit = VMInitCallback;
Alex Lightb6f34642018-01-04 11:01:48 -080074 callbacks.VMDeath = VMDeathCallback;
Andreas Gampe3a7eb142017-01-19 21:59:22 -080075 jvmtiError ret = env->SetEventCallbacks(&callbacks, sizeof(callbacks));
76 if (ret != JVMTI_ERROR_NONE) {
77 printf("Failed to install callbacks");
78 }
79
80 EnableEvent(env, JVMTI_EVENT_VM_START);
81 EnableEvent(env, JVMTI_EVENT_VM_INIT);
82 EnableEvent(env, JVMTI_EVENT_VM_DEATH);
83}
84
Alex Light49948e92016-08-11 15:35:28 -070085jint OnLoad(JavaVM* vm,
86 char* options ATTRIBUTE_UNUSED,
87 void* reserved ATTRIBUTE_UNUSED) {
88 printf("Loaded Agent for test 901-hello-ti-agent\n");
89 fsync(1);
90 jvmtiEnv* env = nullptr;
91 jvmtiEnv* env2 = nullptr;
92
93#define CHECK_CALL_SUCCESS(c) \
94 do { \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -070095 if ((c) != JNI_OK) { \
Alex Light49948e92016-08-11 15:35:28 -070096 printf("call " #c " did not succeed\n"); \
97 return -1; \
98 } \
99 } while (false)
100
101 CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env), JVMTI_VERSION_1_0));
102 CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env2), JVMTI_VERSION_1_0));
103 if (env == env2) {
104 printf("GetEnv returned same environment twice!\n");
105 return -1;
106 }
107 unsigned char* local_data = nullptr;
108 CHECK_CALL_SUCCESS(env->Allocate(8, &local_data));
109 strcpy(reinterpret_cast<char*>(local_data), "hello!!");
110 CHECK_CALL_SUCCESS(env->SetEnvironmentLocalStorage(local_data));
111 unsigned char* get_data = nullptr;
112 CHECK_CALL_SUCCESS(env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data)));
113 if (get_data != local_data) {
114 printf("Got different data from local storage then what was set!\n");
115 return -1;
116 }
117 CHECK_CALL_SUCCESS(env2->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data)));
118 if (get_data != nullptr) {
119 printf("env2 did not have nullptr local storage.\n");
120 return -1;
121 }
122 CHECK_CALL_SUCCESS(env->Deallocate(local_data));
123 jint version = 0;
124 CHECK_CALL_SUCCESS(env->GetVersionNumber(&version));
125 if ((version & JVMTI_VERSION_1) != JVMTI_VERSION_1) {
126 printf("Unexpected version number!\n");
127 return -1;
128 }
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800129
130 InstallVMEvents(env);
131 InstallVMEvents(env2);
132
Alex Light49948e92016-08-11 15:35:28 -0700133 CHECK_CALL_SUCCESS(env->DisposeEnvironment());
134 CHECK_CALL_SUCCESS(env2->DisposeEnvironment());
135#undef CHECK_CALL_SUCCESS
Andreas Gampef37e3022017-01-13 17:54:46 -0800136
137 if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
138 printf("Unable to get jvmti env!\n");
139 return 1;
140 }
Alex Light3d324fd2017-07-20 15:38:52 -0700141 SetStandardCapabilities(jvmti_env);
Andreas Gampef37e3022017-01-13 17:54:46 -0800142
Andreas Gampe96eca782017-01-19 19:45:30 -0800143 jvmtiPhase current_phase;
144 jvmtiError phase_result = jvmti_env->GetPhase(&current_phase);
145 if (phase_result != JVMTI_ERROR_NONE) {
146 printf("Could not get phase");
147 return 1;
148 }
149 if (current_phase != JVMTI_PHASE_ONLOAD) {
150 printf("Wrong phase");
151 return 1;
152 }
153
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800154 InstallVMEvents(jvmti_env);
155
Alex Light49948e92016-08-11 15:35:28 -0700156 return JNI_OK;
157}
158
Andreas Gampe46651672017-04-07 09:00:04 -0700159extern "C" JNIEXPORT void JNICALL Java_art_Test901_setVerboseFlag(
Andreas Gampef37e3022017-01-13 17:54:46 -0800160 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jint iflag, jboolean val) {
161 jvmtiVerboseFlag flag = static_cast<jvmtiVerboseFlag>(iflag);
162 jvmtiError result = jvmti_env->SetVerboseFlag(flag, val);
Andreas Gampe3f46c962017-03-30 10:26:59 -0700163 JvmtiErrorToException(env, jvmti_env, result);
Andreas Gampef37e3022017-01-13 17:54:46 -0800164}
Alex Light49948e92016-08-11 15:35:28 -0700165
Andreas Gampe46651672017-04-07 09:00:04 -0700166extern "C" JNIEXPORT jboolean JNICALL Java_art_Test901_checkLivePhase(
Andreas Gampe96eca782017-01-19 19:45:30 -0800167 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
168 jvmtiPhase current_phase;
169 jvmtiError phase_result = jvmti_env->GetPhase(&current_phase);
Andreas Gampe3f46c962017-03-30 10:26:59 -0700170 if (JvmtiErrorToException(env, jvmti_env, phase_result)) {
Andreas Gampe96eca782017-01-19 19:45:30 -0800171 return JNI_FALSE;
172 }
173 return (current_phase == JVMTI_PHASE_LIVE) ? JNI_TRUE : JNI_FALSE;
174}
175
Alex Light1edc8cf2017-03-24 14:22:56 -0700176static void CallJvmtiFunction(jvmtiEnv* env, jclass klass, jvmtiError* err) {
177 jint n;
178 jmethodID* methods = nullptr;
179 *err = env->GetClassMethods(klass, &n, &methods);
180}
181
Andreas Gampe46651672017-04-07 09:00:04 -0700182extern "C" JNIEXPORT jboolean JNICALL Java_art_Test901_checkUnattached(
Alex Light1edc8cf2017-03-24 14:22:56 -0700183 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass) {
184 jvmtiError res = JVMTI_ERROR_NONE;
185 std::thread t1(CallJvmtiFunction, jvmti_env, Main_klass, &res);
186 t1.join();
187 return res == JVMTI_ERROR_UNATTACHED_THREAD;
188}
189
Andreas Gampe95c466d2017-05-08 14:50:47 -0700190extern "C" JNIEXPORT jstring JNICALL Java_art_Test901_getErrorName(
191 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jint error) {
192 char* name;
193 jvmtiError res = jvmti_env->GetErrorName(static_cast<jvmtiError>(error), &name);
194 if (JvmtiErrorToException(env, jvmti_env, res)) {
195 return nullptr;
196 }
197
198 jstring ret_string = env->NewStringUTF(name);
199 jvmtiError dealloc = jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
200 if (JvmtiErrorToException(env, jvmti_env, dealloc)) {
201 return nullptr;
202 }
203
204 return ret_string;
205}
206
Alex Light49948e92016-08-11 15:35:28 -0700207} // namespace Test901HelloTi
208} // namespace art