diff options
-rw-r--r-- | compiler/driver/compiler_driver.cc | 13 | ||||
-rw-r--r-- | runtime/base/logging.cc | 31 | ||||
-rw-r--r-- | runtime/base/logging.h | 1 | ||||
-rw-r--r-- | runtime/class_linker.cc | 4 | ||||
-rw-r--r-- | runtime/class_linker.h | 4 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 25 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.h | 10 | ||||
-rw-r--r-- | runtime/verifier/method_verifier_test.cc | 9 |
8 files changed, 62 insertions, 35 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index ea16cb2662..d29d528c27 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2212,7 +2212,8 @@ void CompilerDriver::Verify(jobject class_loader, class VerifyClassVisitor : public CompilationVisitor { public: - explicit VerifyClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {} + VerifyClassVisitor(const ParallelCompilationManager* manager, LogSeverity log_level) + : manager_(manager), log_level_(log_level) {} virtual void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) OVERRIDE { ATRACE_CALL(); @@ -2250,7 +2251,7 @@ class VerifyClassVisitor : public CompilationVisitor { &class_def, Runtime::Current()->GetCompilerCallbacks(), true /* allow soft failures */, - true /* log hard failures */, + log_level_, &error_msg) == verifier::MethodVerifier::kHardFailure) { LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor) @@ -2259,7 +2260,7 @@ class VerifyClassVisitor : public CompilationVisitor { } } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) { CHECK(klass->IsResolved()) << PrettyClass(klass.Get()); - class_linker->VerifyClass(soa.Self(), klass); + class_linker->VerifyClass(soa.Self(), klass, log_level_); if (klass->IsErroneous()) { // ClassLinker::VerifyClass throws, which isn't useful in the compiler. @@ -2282,6 +2283,7 @@ class VerifyClassVisitor : public CompilationVisitor { private: const ParallelCompilationManager* const manager_; + const LogSeverity log_level_; }; void CompilerDriver::VerifyDexFile(jobject class_loader, @@ -2294,7 +2296,10 @@ void CompilerDriver::VerifyDexFile(jobject class_loader, ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files, thread_pool); - VerifyClassVisitor visitor(&context); + LogSeverity log_level = GetCompilerOptions().AbortOnHardVerifierFailure() + ? LogSeverity::INTERNAL_FATAL + : LogSeverity::WARNING; + VerifyClassVisitor visitor(&context, log_level); context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count); } diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc index 7a620e375b..212e5bd922 100644 --- a/runtime/base/logging.cc +++ b/runtime/base/logging.cc @@ -185,14 +185,15 @@ class LogMessageData { LogMessage::LogMessage(const char* file, unsigned int line, LogSeverity severity, int error) : data_(new LogMessageData(file, line, severity, error)) { if (PrintDirectly(severity)) { - static const char* log_characters = "VDIWEFF"; - CHECK_EQ(strlen(log_characters), INTERNAL_FATAL + 1U); - stream() << ProgramInvocationShortName() << " " << log_characters[static_cast<size_t>(severity)] + static constexpr char kLogCharacters[] = { 'N', 'V', 'D', 'I', 'W', 'E', 'F', 'F' }; + static_assert(arraysize(kLogCharacters) == static_cast<size_t>(INTERNAL_FATAL) + 1, + "Wrong character array size"); + stream() << ProgramInvocationShortName() << " " << kLogCharacters[static_cast<size_t>(severity)] << " " << getpid() << " " << ::art::GetTid() << " " << file << ":" << line << "]"; } } LogMessage::~LogMessage() { - if (!PrintDirectly(data_->GetSeverity())) { + if (!PrintDirectly(data_->GetSeverity()) && data_->GetSeverity() != LogSeverity::NONE) { if (data_->GetSeverity() < gMinimumLogSeverity) { return; // No need to format something we're not going to output. } @@ -236,6 +237,7 @@ std::ostream& LogMessage::stream() { #ifdef __ANDROID__ static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { + ANDROID_LOG_VERBOSE, // NONE, use verbose as stand-in, will never be printed. ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL }; @@ -245,16 +247,20 @@ static_assert(arraysize(kLogSeverityToAndroidLogPriority) == INTERNAL_FATAL + 1, void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity log_severity, const char* message) { + if (log_severity == LogSeverity::NONE) { + return; + } + #ifdef __ANDROID__ const char* tag = ProgramInvocationShortName(); - int priority = kLogSeverityToAndroidLogPriority[log_severity]; + int priority = kLogSeverityToAndroidLogPriority[static_cast<size_t>(log_severity)]; if (priority == ANDROID_LOG_FATAL) { LOG_PRI(priority, tag, "%s:%u] %s", file, line, message); } else { LOG_PRI(priority, tag, "%s", message); } #else - static const char* log_characters = "VDIWEFF"; + static const char* log_characters = "NVDIWEFF"; CHECK_EQ(strlen(log_characters), INTERNAL_FATAL + 1U); char severity = log_characters[log_severity]; fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n", @@ -264,10 +270,14 @@ void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity log_se void LogMessage::LogLineLowStack(const char* file, unsigned int line, LogSeverity log_severity, const char* message) { + if (log_severity == LogSeverity::NONE) { + return; + } + #ifdef __ANDROID__ // Use android_writeLog() to avoid stack-based buffers used by android_printLog(). const char* tag = ProgramInvocationShortName(); - int priority = kLogSeverityToAndroidLogPriority[log_severity]; + int priority = kLogSeverityToAndroidLogPriority[static_cast<size_t>(log_severity)]; char* buf = nullptr; size_t buf_size = 0u; if (priority == ANDROID_LOG_FATAL) { @@ -285,13 +295,14 @@ void LogMessage::LogLineLowStack(const char* file, unsigned int line, LogSeverit android_writeLog(priority, tag, message); } #else - static const char* log_characters = "VDIWEFF"; - CHECK_EQ(strlen(log_characters), INTERNAL_FATAL + 1U); + static constexpr char kLogCharacters[] = { 'N', 'V', 'D', 'I', 'W', 'E', 'F', 'F' }; + static_assert(arraysize(kLogCharacters) == static_cast<size_t>(INTERNAL_FATAL) + 1, + "Wrong character array size"); const char* program_name = ProgramInvocationShortName(); TEMP_FAILURE_RETRY(write(STDERR_FILENO, program_name, strlen(program_name))); TEMP_FAILURE_RETRY(write(STDERR_FILENO, " ", 1)); - TEMP_FAILURE_RETRY(write(STDERR_FILENO, &log_characters[log_severity], 1)); + TEMP_FAILURE_RETRY(write(STDERR_FILENO, &kLogCharacters[static_cast<size_t>(log_severity)], 1)); TEMP_FAILURE_RETRY(write(STDERR_FILENO, " ", 1)); // TODO: pid and tid. TEMP_FAILURE_RETRY(write(STDERR_FILENO, file, strlen(file))); diff --git a/runtime/base/logging.h b/runtime/base/logging.h index 8aaeaac0dc..97280c3a03 100644 --- a/runtime/base/logging.h +++ b/runtime/base/logging.h @@ -24,6 +24,7 @@ namespace art { enum LogSeverity { + NONE, // Fake level, don't log at all. VERBOSE, DEBUG, INFO, diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 99e38d9fcf..f2c2f03003 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -3750,7 +3750,7 @@ bool ClassLinker::AttemptSupertypeVerification(Thread* self, return false; } -void ClassLinker::VerifyClass(Thread* self, Handle<mirror::Class> klass) { +void ClassLinker::VerifyClass(Thread* self, Handle<mirror::Class> klass, LogSeverity log_level) { // TODO: assert that the monitor on the Class is held ObjectLock<mirror::Class> lock(self, klass); @@ -3853,7 +3853,7 @@ void ClassLinker::VerifyClass(Thread* self, Handle<mirror::Class> klass) { klass.Get(), runtime->GetCompilerCallbacks(), runtime->IsAotCompiler(), - runtime->IsAotCompiler(), + log_level, &error_msg); } if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) { diff --git a/runtime/class_linker.h b/runtime/class_linker.h index b4fbe1c43f..886f586704 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -449,7 +449,9 @@ class ClassLinker { SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - void VerifyClass(Thread* self, Handle<mirror::Class> klass) + void VerifyClass(Thread* self, + Handle<mirror::Class> klass, + LogSeverity log_level = LogSeverity::NONE) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_); bool VerifyClassUsingOatFile(const DexFile& dex_file, diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 5109443d00..3d5f84ef7d 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -122,7 +122,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, mirror::Class* klass, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, std::string* error) { if (klass->IsVerified()) { return kNoFailure; @@ -161,7 +161,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, class_def, callbacks, allow_soft_failures, - log_hard_failures, + log_level, error); } @@ -195,7 +195,7 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethods(Thread* self, Handle<mirror::ClassLoader> class_loader, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, bool need_precise_constants, std::string* error_string) { DCHECK(it != nullptr); @@ -236,7 +236,7 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethods(Thread* self, it->GetMethodAccessFlags(), callbacks, allow_soft_failures, - log_hard_failures, + log_level, need_precise_constants, &hard_failure_msg); if (result.kind == kHardFailure) { @@ -266,7 +266,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, const DexFile::ClassDef* class_def, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, std::string* error) { DCHECK(class_def != nullptr); ScopedTrace trace(__FUNCTION__); @@ -299,7 +299,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, class_loader, callbacks, allow_soft_failures, - log_hard_failures, + log_level, false /* need precise constants */, error); // Virtual methods. @@ -312,7 +312,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, class_loader, callbacks, allow_soft_failures, - log_hard_failures, + log_level, false /* need precise constants */, error); @@ -360,7 +360,7 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, uint32_t method_access_flags, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, bool need_precise_constants, std::string* hard_failure_msg) { MethodVerifier::FailureData result; @@ -407,9 +407,12 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, result.kind = kSoftFailure; } else { CHECK(verifier.have_pending_hard_failure_); - if (VLOG_IS_ON(verifier) || log_hard_failures) { - verifier.DumpFailures(LOG(INFO) << "Verification error in " - << PrettyMethod(method_idx, *dex_file) << "\n"); + if (VLOG_IS_ON(verifier)) { + log_level = LogSeverity::VERBOSE; + } + if (log_level > LogSeverity::VERBOSE) { + verifier.DumpFailures(LOG(log_level) << "Verification error in " + << PrettyMethod(method_idx, *dex_file) << "\n"); } if (hard_failure_msg != nullptr) { CHECK(!verifier.failure_messages_.empty()); diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index ba9bca0565..ebb0b8c1fb 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -142,12 +142,12 @@ class MethodVerifier { kHardFailure, }; - /* Verify a class. Returns "kNoFailure" on success. */ + // Verify a class. Returns "kNoFailure" on success. static FailureKind VerifyClass(Thread* self, mirror::Class* klass, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, std::string* error) SHARED_REQUIRES(Locks::mutator_lock_); static FailureKind VerifyClass(Thread* self, @@ -157,7 +157,7 @@ class MethodVerifier { const DexFile::ClassDef* class_def, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, std::string* error) SHARED_REQUIRES(Locks::mutator_lock_); @@ -331,7 +331,7 @@ class MethodVerifier { Handle<mirror::ClassLoader> class_loader, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, bool need_precise_constants, std::string* error_string) SHARED_REQUIRES(Locks::mutator_lock_); @@ -357,7 +357,7 @@ class MethodVerifier { uint32_t method_access_flags, CompilerCallbacks* callbacks, bool allow_soft_failures, - bool log_hard_failures, + LogSeverity log_level, bool need_precise_constants, std::string* hard_failure_msg) SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc index 946f842fd0..b036313feb 100644 --- a/runtime/verifier/method_verifier_test.cc +++ b/runtime/verifier/method_verifier_test.cc @@ -37,8 +37,13 @@ class MethodVerifierTest : public CommonRuntimeTest { // Verify the class std::string error_msg; - ASSERT_TRUE(MethodVerifier::VerifyClass(self, klass, nullptr, true, true, &error_msg) - == MethodVerifier::kNoFailure) << error_msg; + MethodVerifier::FailureKind failure = MethodVerifier::VerifyClass(self, + klass, + nullptr, + true, + LogSeverity::WARNING, + &error_msg); + ASSERT_TRUE(failure == MethodVerifier::kNoFailure) << error_msg; } void VerifyDexFile(const DexFile& dex) |