ART: Fix GetSystemProperty (2)
Add live-phase Java-call fallback for java.library.path.
Bug: 31455788
Test: manual
Change-Id: Ic7d75e1e17760fce5506359058b754eb283b9c41
diff --git a/runtime/openjdkjvmti/ti_properties.cc b/runtime/openjdkjvmti/ti_properties.cc
index fd67c59..8ee5366 100644
--- a/runtime/openjdkjvmti/ti_properties.cc
+++ b/runtime/openjdkjvmti/ti_properties.cc
@@ -34,8 +34,15 @@
#include <string.h>
#include <vector>
+#include "jni.h"
+#include "ScopedLocalRef.h"
+#include "ScopedUtfChars.h"
+
#include "art_jvmti.h"
#include "runtime.h"
+#include "thread-inl.h"
+#include "ti_phase.h"
+#include "well_known_classes.h"
namespace openjdkjvmti {
@@ -150,6 +157,51 @@
return class_path.empty() ? "." : class_path.c_str();
}
+// Handle kPropertyLibraryPath.
+static jvmtiError GetLibraryPath(jvmtiEnv* env, char** value_ptr) {
+ const std::vector<std::string>& runtime_props = art::Runtime::Current()->GetProperties();
+ for (const std::string& prop_assignment : runtime_props) {
+ size_t assign_pos = prop_assignment.find('=');
+ if (assign_pos != std::string::npos && assign_pos > 0) {
+ if (prop_assignment.substr(0, assign_pos) == kPropertyLibraryPath) {
+ return Copy(env, prop_assignment.substr(assign_pos + 1).c_str(), value_ptr);
+ }
+ }
+ }
+ if (!PhaseUtil::IsLivePhase()) {
+ return ERR(NOT_AVAILABLE);
+ }
+ // We expect this call to be rare. So don't optimize.
+ DCHECK(art::Thread::Current() != nullptr);
+ JNIEnv* jni_env = art::Thread::Current()->GetJniEnv();
+ jmethodID get_prop = jni_env->GetStaticMethodID(art::WellKnownClasses::java_lang_System,
+ "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;");
+ CHECK(get_prop != nullptr);
+
+ ScopedLocalRef<jobject> input_str(jni_env, jni_env->NewStringUTF(kPropertyLibraryPath));
+ if (input_str.get() == nullptr) {
+ jni_env->ExceptionClear();
+ return ERR(OUT_OF_MEMORY);
+ }
+
+ ScopedLocalRef<jobject> prop_res(
+ jni_env, jni_env->CallStaticObjectMethod(art::WellKnownClasses::java_lang_System,
+ get_prop,
+ input_str.get()));
+ if (jni_env->ExceptionCheck() == JNI_TRUE) {
+ jni_env->ExceptionClear();
+ return ERR(INTERNAL);
+ }
+ if (prop_res.get() == nullptr) {
+ *value_ptr = nullptr;
+ return ERR(NONE);
+ }
+
+ ScopedUtfChars chars(jni_env, reinterpret_cast<jstring>(prop_res.get()));
+ return Copy(env, chars.c_str(), value_ptr);
+}
+
jvmtiError PropertiesUtil::GetSystemProperty(jvmtiEnv* env,
const char* property,
char** value_ptr) {
@@ -158,18 +210,7 @@
}
if (strcmp(property, kPropertyLibraryPath) == 0) {
- // TODO: In the live phase, we should probably compare to System.getProperty. java.library.path
- // may not be set initially, and is then freely modifiable.
- const std::vector<std::string>& runtime_props = art::Runtime::Current()->GetProperties();
- for (const std::string& prop_assignment : runtime_props) {
- size_t assign_pos = prop_assignment.find('=');
- if (assign_pos != std::string::npos && assign_pos > 0) {
- if (prop_assignment.substr(0, assign_pos) == kPropertyLibraryPath) {
- return Copy(env, prop_assignment.substr(assign_pos + 1).c_str(), value_ptr);
- }
- }
- }
- return ERR(NOT_AVAILABLE);
+ return GetLibraryPath(env, value_ptr);
}
if (strcmp(property, kPropertyClassPath) == 0) {