summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2020-02-24 14:31:54 -0800
committer Treehugger Robot <treehugger-gerrit@google.com> 2020-02-25 17:20:07 +0000
commit8f95183e07398b31fd922f132b8ed2f64950dd28 (patch)
tree065562c40fdadbd530279175437c52dc20773c8e
parenteac404b341e40bb72f8d79ee1d1a7173862b438e (diff)
Add new set_verbose_flag_ext JVMTI Extension
Add a new jvmti extension function "com.android.art.misc.set_verbose_flag_ext" that enables one to set (or disable) verbose logging options using strings with the same format as the '-verbose:' command line flag. Bug: 144947842 Test: atest CtsJvmtiRunTest1982HostTestCases Change-Id: Ideb1663f5cacfacaeab8cc180372ef479dfc5829
-rw-r--r--openjdkjvmti/Android.bp1
-rw-r--r--openjdkjvmti/OpenjdkJvmTi.cc55
-rw-r--r--openjdkjvmti/ti_extension.cc21
-rw-r--r--openjdkjvmti/ti_logging.cc90
-rw-r--r--openjdkjvmti/ti_logging.h3
5 files changed, 116 insertions, 54 deletions
diff --git a/openjdkjvmti/Android.bp b/openjdkjvmti/Android.bp
index 9ec9dea7e1..3aab1ffa07 100644
--- a/openjdkjvmti/Android.bp
+++ b/openjdkjvmti/Android.bp
@@ -58,6 +58,7 @@ cc_defaults {
"transform.cc",
],
header_libs: [
+ "art_cmdlineparser_headers",
"libnativehelper_header_only",
"libopenjdkjvmti_headers",
],
diff --git a/openjdkjvmti/OpenjdkJvmTi.cc b/openjdkjvmti/OpenjdkJvmTi.cc
index 4ce376ff9b..a5c5df6cc9 100644
--- a/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/openjdkjvmti/OpenjdkJvmTi.cc
@@ -1376,60 +1376,7 @@ class JvmtiFunctions {
jvmtiVerboseFlag flag,
jboolean value) {
ENSURE_VALID_ENV(env);
- if (flag == jvmtiVerboseFlag::JVMTI_VERBOSE_OTHER) {
- // OTHER is special, as it's 0, so can't do a bit check.
- bool val = (value == JNI_TRUE) ? true : false;
-
- art::gLogVerbosity.collector = val;
- art::gLogVerbosity.compiler = val;
- art::gLogVerbosity.deopt = val;
- art::gLogVerbosity.heap = val;
- art::gLogVerbosity.interpreter = val;
- art::gLogVerbosity.jdwp = val;
- art::gLogVerbosity.jit = val;
- art::gLogVerbosity.monitor = val;
- art::gLogVerbosity.oat = val;
- art::gLogVerbosity.profiler = val;
- art::gLogVerbosity.signals = val;
- art::gLogVerbosity.simulator = val;
- art::gLogVerbosity.startup = val;
- art::gLogVerbosity.third_party_jni = val;
- art::gLogVerbosity.threads = val;
- art::gLogVerbosity.verifier = val;
- // Do not set verifier-debug.
- art::gLogVerbosity.image = val;
- art::gLogVerbosity.plugin = val;
-
- // Note: can't switch systrace_lock_logging. That requires changing entrypoints.
-
- art::gLogVerbosity.agents = val;
- } else {
- // Spec isn't clear whether "flag" is a mask or supposed to be single. We implement the mask
- // semantics.
- constexpr std::underlying_type<jvmtiVerboseFlag>::type kMask =
- jvmtiVerboseFlag::JVMTI_VERBOSE_GC |
- jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS |
- jvmtiVerboseFlag::JVMTI_VERBOSE_JNI;
- if ((flag & ~kMask) != 0) {
- return ERR(ILLEGAL_ARGUMENT);
- }
-
- bool val = (value == JNI_TRUE) ? true : false;
-
- if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_GC) != 0) {
- art::gLogVerbosity.gc = val;
- }
-
- if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS) != 0) {
- art::gLogVerbosity.class_linker = val;
- }
-
- if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_JNI) != 0) {
- art::gLogVerbosity.jni = val;
- }
- }
-
- return ERR(NONE);
+ return LogUtil::SetVerboseFlag(env, flag, value);
}
static jvmtiError GetJLocationFormat(jvmtiEnv* env, jvmtiJlocationFormat* format_ptr) {
diff --git a/openjdkjvmti/ti_extension.cc b/openjdkjvmti/ti_extension.cc
index 62c6fb24ef..f3f6e18018 100644
--- a/openjdkjvmti/ti_extension.cc
+++ b/openjdkjvmti/ti_extension.cc
@@ -488,6 +488,27 @@ jvmtiError ExtensionUtil::GetExtensionFunctions(jvmtiEnv* env,
LOG(INFO) << "debuggable & jni-type indices are required to implement structural "
<< "class redefinition extensions.";
}
+ // SetVerboseFlagExt
+ error = add_extension(
+ reinterpret_cast<jvmtiExtensionFunction>(LogUtil::SetVerboseFlagExt),
+ "com.android.art.misc.set_verbose_flag_ext",
+ "Sets the verbose flags selected by the 'option' c-string. Valid options are anything that"
+ " would be accepted by the -verbose:<option> runtime flag. The verbose selections are turned"
+ " on if 'enable' is set to true and disabled otherwise. You may select multiple options at"
+ " once using commas just like with the -verbose:<option> flag. For example \"class,deopt,gc\""
+ " is equivalent to turning on all of the VLOG(class_linker), VLOG(deopt) and VLOG(gc)"
+ " messages.",
+ {
+ { "option", JVMTI_KIND_IN_BUF, JVMTI_TYPE_CCHAR, false },
+ { "enable", JVMTI_KIND_IN, JVMTI_TYPE_JBOOLEAN, false },
+ },
+ {
+ ERR(NULL_POINTER),
+ ERR(ILLEGAL_ARGUMENT),
+ });
+ if (error != ERR(NONE)) {
+ return error;
+ }
// Copy into output buffer.
diff --git a/openjdkjvmti/ti_logging.cc b/openjdkjvmti/ti_logging.cc
index 60f4340fc7..8740ec65c2 100644
--- a/openjdkjvmti/ti_logging.cc
+++ b/openjdkjvmti/ti_logging.cc
@@ -33,8 +33,11 @@
#include "art_jvmti.h"
+#include "base/logging.h"
#include "base/mutex.h"
#include "base/strlcpy.h"
+#include "cmdline_types.h"
+#include "jvmti.h"
#include "thread-current-inl.h"
namespace openjdkjvmti {
@@ -69,4 +72,91 @@ jvmtiError LogUtil::ClearLastError(jvmtiEnv* env) {
return OK;
}
+jvmtiError LogUtil::SetVerboseFlagExt(jvmtiEnv* env, const char* data, jboolean enable) {
+ if (env == nullptr) {
+ return ERR(INVALID_ENVIRONMENT);
+ } else if (data == nullptr) {
+ return ERR(NULL_POINTER);
+ }
+ bool new_value = (enable == JNI_TRUE) ? true : false;
+ art::CmdlineType<art::LogVerbosity> cmdline_parser;
+ std::string parse_data(data);
+ art::CmdlineType<art::LogVerbosity>::Result result = cmdline_parser.Parse(parse_data);
+ if (result.IsError()) {
+ JVMTI_LOG(INFO, env) << "Invalid verbose argument: '" << parse_data << "'. Error was "
+ << result.GetMessage();
+ return ERR(ILLEGAL_ARGUMENT);
+ }
+
+ const art::LogVerbosity& input_verbosity = result.GetValue();
+ const bool* verbosity_arr = reinterpret_cast<const bool*>(&input_verbosity);
+ bool* g_log_verbosity_arr = reinterpret_cast<bool*>(&art::gLogVerbosity);
+ // Copy/invert the verbosity byte-by-byte (sizeof(bool) == 1).
+ for (size_t i = 0; i < sizeof(art::LogVerbosity); i++) {
+ if (verbosity_arr[i]) {
+ g_log_verbosity_arr[i] = new_value;
+ }
+ }
+ return OK;
+}
+
+jvmtiError LogUtil::SetVerboseFlag(jvmtiEnv* env ATTRIBUTE_UNUSED,
+ jvmtiVerboseFlag flag,
+ jboolean value) {
+ if (flag == jvmtiVerboseFlag::JVMTI_VERBOSE_OTHER) {
+ // OTHER is special, as it's 0, so can't do a bit check.
+ bool val = (value == JNI_TRUE) ? true : false;
+
+ art::gLogVerbosity.collector = val;
+ art::gLogVerbosity.compiler = val;
+ art::gLogVerbosity.deopt = val;
+ art::gLogVerbosity.heap = val;
+ art::gLogVerbosity.interpreter = val;
+ art::gLogVerbosity.jdwp = val;
+ art::gLogVerbosity.jit = val;
+ art::gLogVerbosity.monitor = val;
+ art::gLogVerbosity.oat = val;
+ art::gLogVerbosity.profiler = val;
+ art::gLogVerbosity.signals = val;
+ art::gLogVerbosity.simulator = val;
+ art::gLogVerbosity.startup = val;
+ art::gLogVerbosity.third_party_jni = val;
+ art::gLogVerbosity.threads = val;
+ art::gLogVerbosity.verifier = val;
+ // Do not set verifier-debug.
+ art::gLogVerbosity.image = val;
+ art::gLogVerbosity.plugin = val;
+
+ // Note: can't switch systrace_lock_logging. That requires changing entrypoints.
+
+ art::gLogVerbosity.agents = val;
+ } else {
+ // Spec isn't clear whether "flag" is a mask or supposed to be single. We implement the mask
+ // semantics.
+ constexpr std::underlying_type<jvmtiVerboseFlag>::type kMask =
+ jvmtiVerboseFlag::JVMTI_VERBOSE_GC |
+ jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS |
+ jvmtiVerboseFlag::JVMTI_VERBOSE_JNI;
+ if ((flag & ~kMask) != 0) {
+ return ERR(ILLEGAL_ARGUMENT);
+ }
+
+ bool val = (value == JNI_TRUE) ? true : false;
+
+ if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_GC) != 0) {
+ art::gLogVerbosity.gc = val;
+ }
+
+ if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS) != 0) {
+ art::gLogVerbosity.class_linker = val;
+ }
+
+ if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_JNI) != 0) {
+ art::gLogVerbosity.jni = val;
+ }
+ }
+
+ return ERR(NONE);
+}
+
} // namespace openjdkjvmti
diff --git a/openjdkjvmti/ti_logging.h b/openjdkjvmti/ti_logging.h
index b4ce5b6810..fc814efe99 100644
--- a/openjdkjvmti/ti_logging.h
+++ b/openjdkjvmti/ti_logging.h
@@ -94,6 +94,9 @@ class LogUtil {
public:
static jvmtiError ClearLastError(jvmtiEnv* env);
static jvmtiError GetLastError(jvmtiEnv* env, char** data);
+
+ static jvmtiError SetVerboseFlag(jvmtiEnv* env, jvmtiVerboseFlag flag, jboolean value);
+ static jvmtiError SetVerboseFlagExt(jvmtiEnv* env, const char* data, jboolean enable);
};
} // namespace openjdkjvmti