diff options
author | 2020-02-24 14:31:54 -0800 | |
---|---|---|
committer | 2020-02-25 17:20:07 +0000 | |
commit | 8f95183e07398b31fd922f132b8ed2f64950dd28 (patch) | |
tree | 065562c40fdadbd530279175437c52dc20773c8e | |
parent | eac404b341e40bb72f8d79ee1d1a7173862b438e (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.bp | 1 | ||||
-rw-r--r-- | openjdkjvmti/OpenjdkJvmTi.cc | 55 | ||||
-rw-r--r-- | openjdkjvmti/ti_extension.cc | 21 | ||||
-rw-r--r-- | openjdkjvmti/ti_logging.cc | 90 | ||||
-rw-r--r-- | openjdkjvmti/ti_logging.h | 3 |
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 |