summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2018-06-19 10:45:54 -0700
committer Andreas Gampe <agampe@google.com> 2018-06-19 12:34:35 -0700
commit7b2450ed72abe2636ea8d791bb9b37c3b5f15b4b (patch)
treef016684aa3328e94e7eefaf467db6230c3b3ad0d
parent7a55ce0fed42310e6ff71e3fd648ea715c40aa83 (diff)
ART: Verify StackOverflowError early
When running sanitized, ensure that the StackOverflowError class is verified at startup. Otherwise, having to verify it when throwing may not have enough stack space. Bug: 109813469 Test: SANITIZE_HOST=address art/test/testrunner/testrunner.py -b --host --interp-ac -t 1934 Change-Id: Ie8cec840329d99c3e485fb9217740a76b1d12a46
-rw-r--r--runtime/class_linker.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c374e03ed7..22bd37d22c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -805,7 +805,7 @@ void ClassLinker::FinishInit(Thread* self) {
// Note: we hard code the field indexes here rather than using FindInstanceField
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
- StackHandleScope<2> hs(self);
+ StackHandleScope<3> hs(self);
Handle<mirror::Class> java_lang_ref_Reference =
hs.NewHandle(GetClassRoot<mirror::Reference>(this));
Handle<mirror::Class> java_lang_ref_FinalizerReference =
@@ -847,6 +847,20 @@ void ClassLinker::FinishInit(Thread* self) {
// that Object, Class, and Object[] are setup
init_done_ = true;
+ // Under sanitization, the small carve-out to handle stack overflow might not be enough to
+ // initialize the StackOverflowError class (as it might require running the verifier). Instead,
+ // ensure that the class will be initialized.
+ if (kMemoryToolIsAvailable && !Runtime::Current()->IsAotCompiler()) {
+ verifier::MethodVerifier::Init(); // Need to prepare the verifier.
+
+ ObjPtr<mirror::Class> soe_klass = FindSystemClass(self, "Ljava/lang/StackOverflowError;");
+ if (soe_klass == nullptr || !EnsureInitialized(self, hs.NewHandle(soe_klass), true, true)) {
+ // Strange, but don't crash.
+ LOG(WARNING) << "Could not prepare StackOverflowError.";
+ self->ClearException();
+ }
+ }
+
VLOG(startup) << "ClassLinker::FinishInit exiting";
}