Cleanup of redefinition testing
Move redefine logic into a single common function and perform some
other cleanup.
Test: mma -j40 test-art-host
Change-Id: I8618bda4f392b683ce198374066e356b87578e7b
diff --git a/test/902-hello-transformation/expected.txt b/test/902-hello-transformation/expected.txt
index a826f93..4774b81 100644
--- a/test/902-hello-transformation/expected.txt
+++ b/test/902-hello-transformation/expected.txt
@@ -1,3 +1,2 @@
hello
-modifying class 'Transform'
Goodbye
diff --git a/test/902-hello-transformation/run b/test/902-hello-transformation/run
index 3755d1d..94a8b2d 100755
--- a/test/902-hello-transformation/run
+++ b/test/902-hello-transformation/run
@@ -27,12 +27,11 @@
arg="jvm"
else
arg="art"
-fi
-
-if [[ "$@" != *"--debuggable"* ]]; then
- other_args=" -Xcompiler-option --debuggable "
-else
- other_args=""
+ if [[ "$@" != *"--debuggable"* ]]; then
+ other_args=" -Xcompiler-option --debuggable "
+ else
+ other_args=""
+ fi
fi
./default-run "$@" --experimental agents \
diff --git a/test/902-hello-transformation/src/Main.java b/test/902-hello-transformation/src/Main.java
index 204b6e7..ec47119 100644
--- a/test/902-hello-transformation/src/Main.java
+++ b/test/902-hello-transformation/src/Main.java
@@ -14,7 +14,40 @@
* limitations under the License.
*/
+import java.util.Base64;
public class Main {
+
+ /**
+ * base64 encoded class/dex file for
+ * class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" +
+ "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" +
+ "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" +
+ "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG" +
+ "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" +
+ "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0=");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
+ "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
+ "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
+ "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
+ "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
+ "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
+ "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
+ "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
+ "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
+ "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
+ "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
+ "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
+ "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=");
+
public static void main(String[] args) {
System.loadLibrary(args[1]);
doTest(new Transform());
@@ -22,10 +55,12 @@
public static void doTest(Transform t) {
t.sayHi();
- doClassTransformation(Transform.class);
+ doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
t.sayHi();
}
// Transforms the class
- private static native void doClassTransformation(Class target);
+ private static native void doCommonClassRedefinition(Class<?> target,
+ byte[] class_file,
+ byte[] dex_file);
}
diff --git a/test/902-hello-transformation/transform.cc b/test/902-hello-transformation/transform.cc
deleted file mode 100644
index 3369dd4..0000000
--- a/test/902-hello-transformation/transform.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-#include <pthread.h>
-#include <stdio.h>
-#include <vector>
-
-#include "art_method-inl.h"
-#include "base/logging.h"
-#include "jni.h"
-#include "openjdkjvmti/jvmti.h"
-#include "ti-agent/common_helper.h"
-#include "ti-agent/common_load.h"
-#include "utils.h"
-
-namespace art {
-namespace Test902HelloTransformation {
-
-static bool RuntimeIsJvm = false;
-
-bool IsJVM() {
- return RuntimeIsJvm;
-}
-
-// base64 encoded class/dex file for
-//
-// class Transform {
-// public void sayHi() {
-// System.out.println("Goodbye");
-// }
-// }
-const char* class_file_base64 =
- "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB"
- "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA"
- "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq"
- "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph"
- "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG"
- "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB"
- "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0=";
-
-const char* dex_file_base64 =
- "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO"
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB"
- "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA"
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA"
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA"
- "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA"
- "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50"
- "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh"
- "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291"
- "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA"
- "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA"
- "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA"
- "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=";
-
-static void JNICALL transformationHook(jvmtiEnv *jvmtienv,
- JNIEnv* jni_env ATTRIBUTE_UNUSED,
- jclass class_being_redefined ATTRIBUTE_UNUSED,
- jobject loader ATTRIBUTE_UNUSED,
- const char* name,
- jobject protection_domain ATTRIBUTE_UNUSED,
- jint class_data_len ATTRIBUTE_UNUSED,
- const unsigned char* class_data ATTRIBUTE_UNUSED,
- jint* new_class_data_len,
- unsigned char** new_class_data) {
- if (strcmp("Transform", name)) {
- return;
- }
- printf("modifying class '%s'\n", name);
- bool is_jvm = IsJVM();
- size_t decode_len = 0;
- unsigned char* new_data;
- std::unique_ptr<uint8_t[]> file_data(
- DecodeBase64((is_jvm) ? class_file_base64 : dex_file_base64, &decode_len));
- jvmtiError ret = JVMTI_ERROR_NONE;
- if ((ret = jvmtienv->Allocate(static_cast<jlong>(decode_len), &new_data)) != JVMTI_ERROR_NONE) {
- printf("Unable to allocate buffer!\n");
- return;
- }
- memcpy(new_data, file_data.get(), decode_len);
- *new_class_data_len = static_cast<jint>(decode_len);
- *new_class_data = new_data;
- return;
-}
-
-using RetransformWithHookFunction = jvmtiError (*)(jvmtiEnv*, jclass, jvmtiEventClassFileLoadHook);
-static void DoClassTransformation(jvmtiEnv* jvmtienv, JNIEnv* jnienv, jclass target) {
- if (IsJVM()) {
- UNUSED(jnienv);
- jvmtienv->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, nullptr);
- jvmtiError ret = jvmtienv->RetransformClasses(1, &target);
- if (ret != JVMTI_ERROR_NONE) {
- char* err;
- jvmtienv->GetErrorName(ret, &err);
- printf("Error transforming: %s\n", err);
- }
- } else {
- RetransformWithHookFunction f =
- reinterpret_cast<RetransformWithHookFunction>(jvmtienv->functions->reserved1);
- if (f(jvmtienv, target, transformationHook) != JVMTI_ERROR_NONE) {
- printf("Failed to tranform class!");
- return;
- }
- }
-}
-
-extern "C" JNIEXPORT void JNICALL Java_Main_doClassTransformation(JNIEnv* env,
- jclass,
- jclass target) {
- JavaVM* vm;
- if (env->GetJavaVM(&vm)) {
- printf("Unable to get javaVM!\n");
- return;
- }
- DoClassTransformation(jvmti_env, env, target);
-}
-
-// Don't do anything
-jint OnLoad(JavaVM* vm,
- char* options,
- void* reserved ATTRIBUTE_UNUSED) {
- RuntimeIsJvm = (strcmp("jvm", options) == 0);
- if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
- printf("Unable to get jvmti env!\n");
- return 1;
- }
- SetAllCapabilities(jvmti_env);
- if (IsJVM()) {
- jvmtiEventCallbacks cbs;
- memset(&cbs, 0, sizeof(cbs));
- cbs.ClassFileLoadHook = transformationHook;
- jvmti_env->SetEventCallbacks(&cbs, sizeof(jvmtiEventCallbacks));
- }
- return 0;
-}
-
-} // namespace Test902HelloTransformation
-} // namespace art
-
diff --git a/test/902-hello-transformation/transform.h b/test/902-hello-transformation/transform.h
deleted file mode 100644
index 661058d..0000000
--- a/test/902-hello-transformation/transform.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_TEST_902_HELLO_TRANSFORMATION_TRANSFORM_H_
-#define ART_TEST_902_HELLO_TRANSFORMATION_TRANSFORM_H_
-
-#include <jni.h>
-
-namespace art {
-namespace Test902HelloTransformation {
-
-jint OnLoad(JavaVM* vm, char* options, void* reserved);
-
-} // namespace Test902HelloTransformation
-} // namespace art
-
-#endif // ART_TEST_902_HELLO_TRANSFORMATION_TRANSFORM_H_