ART: Fix GetErrorName.
Add missing case for JVMTI_ERROR_THREAD_SUSPENDED. Also return
JVMTI_ERROR_ILLEGAL_ARGUMENT for unspecified inputs.
Refactor the code
* Remove the switch default case for case checking
* Use a lambda to unify the return code. This saves 4K of so size.
Add a test.
Bug: 38133825
Test: m
Test: art/test/testrunner/testrunner.py -b --host -t 901
Change-Id: If46b276b8abcd8b7b8ebbac1106f6b840761b997
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 4c00317..0921cea 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -1505,23 +1505,26 @@
static jvmtiError GetErrorName(jvmtiEnv* env, jvmtiError error, char** name_ptr) {
ENSURE_NON_NULL(name_ptr);
+ auto copy_fn = [&](const char* name_cstr) {
+ jvmtiError res;
+ JvmtiUniquePtr<char[]> copy = CopyString(env, name_cstr, &res);
+ if (copy == nullptr) {
+ *name_ptr = nullptr;
+ return res;
+ } else {
+ *name_ptr = copy.release();
+ return OK;
+ }
+ };
switch (error) {
-#define ERROR_CASE(e) case (JVMTI_ERROR_ ## e) : do { \
- jvmtiError res; \
- JvmtiUniquePtr<char[]> copy = CopyString(env, "JVMTI_ERROR_"#e, &res); \
- if (copy == nullptr) { \
- *name_ptr = nullptr; \
- return res; \
- } else { \
- *name_ptr = copy.release(); \
- return OK; \
- } \
- } while (false)
+#define ERROR_CASE(e) case (JVMTI_ERROR_ ## e) : \
+ return copy_fn("JVMTI_ERROR_"#e);
ERROR_CASE(NONE);
ERROR_CASE(INVALID_THREAD);
ERROR_CASE(INVALID_THREAD_GROUP);
ERROR_CASE(INVALID_PRIORITY);
ERROR_CASE(THREAD_NOT_SUSPENDED);
+ ERROR_CASE(THREAD_SUSPENDED);
ERROR_CASE(THREAD_NOT_ALIVE);
ERROR_CASE(INVALID_OBJECT);
ERROR_CASE(INVALID_CLASS);
@@ -1566,18 +1569,9 @@
ERROR_CASE(UNATTACHED_THREAD);
ERROR_CASE(INVALID_ENVIRONMENT);
#undef ERROR_CASE
- default: {
- jvmtiError res;
- JvmtiUniquePtr<char[]> copy = CopyString(env, "JVMTI_ERROR_UNKNOWN", &res);
- if (copy == nullptr) {
- *name_ptr = nullptr;
- return res;
- } else {
- *name_ptr = copy.release();
- return ERR(ILLEGAL_ARGUMENT);
- }
- }
}
+
+ return ERR(ILLEGAL_ARGUMENT);
}
static jvmtiError SetVerboseFlag(jvmtiEnv* env,
diff --git a/test/901-hello-ti-agent/basics.cc b/test/901-hello-ti-agent/basics.cc
index 8695e0c..21dcf98 100644
--- a/test/901-hello-ti-agent/basics.cc
+++ b/test/901-hello-ti-agent/basics.cc
@@ -176,5 +176,22 @@
return res == JVMTI_ERROR_UNATTACHED_THREAD;
}
+extern "C" JNIEXPORT jstring JNICALL Java_art_Test901_getErrorName(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jint error) {
+ char* name;
+ jvmtiError res = jvmti_env->GetErrorName(static_cast<jvmtiError>(error), &name);
+ if (JvmtiErrorToException(env, jvmti_env, res)) {
+ return nullptr;
+ }
+
+ jstring ret_string = env->NewStringUTF(name);
+ jvmtiError dealloc = jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
+ if (JvmtiErrorToException(env, jvmti_env, dealloc)) {
+ return nullptr;
+ }
+
+ return ret_string;
+}
+
} // namespace Test901HelloTi
} // namespace art
diff --git a/test/901-hello-ti-agent/expected.txt b/test/901-hello-ti-agent/expected.txt
index eb5b6a2..4177ffc 100644
--- a/test/901-hello-ti-agent/expected.txt
+++ b/test/901-hello-ti-agent/expected.txt
@@ -10,4 +10,67 @@
4
8
JVMTI_ERROR_ILLEGAL_ARGUMENT
+1 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+0 = JVMTI_ERROR_NONE
+9 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+10 = JVMTI_ERROR_INVALID_THREAD
+11 = JVMTI_ERROR_INVALID_THREAD_GROUP
+12 = JVMTI_ERROR_INVALID_PRIORITY
+13 = JVMTI_ERROR_THREAD_NOT_SUSPENDED
+14 = JVMTI_ERROR_THREAD_SUSPENDED
+15 = JVMTI_ERROR_THREAD_NOT_ALIVE
+4 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+20 = JVMTI_ERROR_INVALID_OBJECT
+21 = JVMTI_ERROR_INVALID_CLASS
+22 = JVMTI_ERROR_CLASS_NOT_PREPARED
+23 = JVMTI_ERROR_INVALID_METHODID
+24 = JVMTI_ERROR_INVALID_LOCATION
+25 = JVMTI_ERROR_INVALID_FIELDID
+5 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+31 = JVMTI_ERROR_NO_MORE_FRAMES
+32 = JVMTI_ERROR_OPAQUE_FRAME
+1 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+34 = JVMTI_ERROR_TYPE_MISMATCH
+35 = JVMTI_ERROR_INVALID_SLOT
+4 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+40 = JVMTI_ERROR_DUPLICATE
+41 = JVMTI_ERROR_NOT_FOUND
+8 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+50 = JVMTI_ERROR_INVALID_MONITOR
+51 = JVMTI_ERROR_NOT_MONITOR_OWNER
+52 = JVMTI_ERROR_INTERRUPT
+7 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+60 = JVMTI_ERROR_INVALID_CLASS_FORMAT
+61 = JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION
+62 = JVMTI_ERROR_FAILS_VERIFICATION
+63 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED
+64 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED
+65 = JVMTI_ERROR_INVALID_TYPESTATE
+66 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED
+67 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED
+68 = JVMTI_ERROR_UNSUPPORTED_VERSION
+69 = JVMTI_ERROR_NAMES_DONT_MATCH
+70 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED
+71 = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED
+7 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+79 = JVMTI_ERROR_UNMODIFIABLE_CLASS
+18 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+98 = JVMTI_ERROR_NOT_AVAILABLE
+99 = JVMTI_ERROR_MUST_POSSESS_CAPABILITY
+100 = JVMTI_ERROR_NULL_POINTER
+101 = JVMTI_ERROR_ABSENT_INFORMATION
+102 = JVMTI_ERROR_INVALID_EVENT_TYPE
+103 = JVMTI_ERROR_ILLEGAL_ARGUMENT
+104 = JVMTI_ERROR_NATIVE_METHOD
+1 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+106 = JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED
+3 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+110 = JVMTI_ERROR_OUT_OF_MEMORY
+111 = JVMTI_ERROR_ACCESS_DENIED
+112 = JVMTI_ERROR_WRONG_PHASE
+113 = JVMTI_ERROR_INTERNAL
+1 times JVMTI_ERROR_ILLEGAL_ARGUMENT
+115 = JVMTI_ERROR_UNATTACHED_THREAD
+116 = JVMTI_ERROR_INVALID_ENVIRONMENT
+1 times JVMTI_ERROR_ILLEGAL_ARGUMENT
VMDeath
diff --git a/test/901-hello-ti-agent/src/art/Test901.java b/test/901-hello-ti-agent/src/art/Test901.java
index eef2188..7d853a7 100644
--- a/test/901-hello-ti-agent/src/art/Test901.java
+++ b/test/901-hello-ti-agent/src/art/Test901.java
@@ -32,6 +32,8 @@
set(2); // CLASS
set(4); // JNI
set(8); // Error.
+
+ testErrorNames();
}
private static void set(int i) {
@@ -44,7 +46,39 @@
}
}
+ private static void testErrorNames() {
+ int consecutiveErrors = 0;
+ String lastError = null;
+ for (int i = -1; i <= 117; i++) {
+ String errorName = null;
+ String error = null;
+ try {
+ errorName = getErrorName(i);
+ } catch (RuntimeException e) {
+ error = e.getMessage();
+ }
+
+ if (lastError != null &&
+ (errorName != null || (error != null && !lastError.equals(error)))) {
+ System.out.println(consecutiveErrors + " times " + lastError);
+ lastError = null;
+ consecutiveErrors = 0;
+ }
+
+ if (errorName != null) {
+ System.out.println(i + " = " + errorName);
+ } else {
+ lastError = error;
+ consecutiveErrors++;
+ }
+ }
+ if (consecutiveErrors > 0) {
+ System.out.println(consecutiveErrors + " times " + lastError);
+ }
+ }
+
private static native boolean checkLivePhase();
private static native void setVerboseFlag(int flag, boolean value);
private static native boolean checkUnattached();
+ private static native String getErrorName(int error);
}