dex2oat: Do not crash on InitializeClass() exceptions.
Previously `ClassLinker::EnsureInitialized()` could have
returned with a pending exception even when initializing
fields and parents was not allowed and the CompilerDriver
did not expect it, leading to a crash. Change the behavior
to consistently suppress exceptions when initializing
fields and/or parents is not allowed.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 184094466
Change-Id: I6a8af8c1da792c946f8f52ed4513ab1f0ccf2c9f
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index fdf52d2..9029693 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -2162,6 +2162,7 @@
// Attempt to initialize the class but bail if we either need to initialize the super-class
// or static fields.
class_linker->EnsureInitialized(self, klass, false, false);
+ DCHECK(!self->IsExceptionPending());
old_status = klass->GetStatus();
if (!klass->IsInitialized()) {
// We don't want non-trivial class initialization occurring on multiple threads due to
@@ -2182,9 +2183,7 @@
is_boot_image ? true : InitializeDependencies(klass, class_loader, self);
if (try_initialize_with_superclasses) {
class_linker->EnsureInitialized(self, klass, false, true);
- // It's OK to clear the exception here since the compiler is supposed to be fault
- // tolerant and will silently not initialize classes that have exceptions.
- self->ClearException();
+ DCHECK(!self->IsExceptionPending());
}
// Otherwise it's in app image or boot image extension but superclasses
// cannot be initialized, no need to proceed.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 745e7cf..df49a3a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5862,6 +5862,10 @@
if (!success) {
if (can_init_fields && can_init_parents) {
CHECK(self->IsExceptionPending()) << c->PrettyClass();
+ } else {
+ // There may or may not be an exception pending. If there is, clear it.
+ // We propagate the exception only if we can initialize fields and parents.
+ self->ClearException();
}
} else {
self->AssertNoPendingException();