Ensure invoking obsolete methods throws errors.
This sets the entrypoint for obsolete methods to a special stub that
will ensure that calling them results in an Error being thrown.
Previously we were allowing obsolete methods to be run if they could
reach the appropriate places in the runtime.
Getting into the state where this is possible is extremely difficult
since one can only get an jmethodID to an obsolete method by snatching
it off the stack (or by inspecting internal runtime data). From there
normally invoking it will do lookup on the receiver which will get you
the original version.
Bug: 36867251
Bug: 31455788
Test: ./test.py --host -j40
Test: (with aosp_marlin-userdebug device) ./test.py --target -j4
Change-Id: I2ca0503966a4e3de18dd89cb7ff224eba1459b49
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 67e949f..bf49e84 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -360,6 +360,14 @@
return;
}
+ // This can happen if we are in forced interpreter mode and an obsolete method is called using
+ // reflection.
+ if (UNLIKELY(method->IsObsolete())) {
+ ThrowInternalError("Attempting to invoke obsolete version of '%s'.",
+ method->PrettyMethod().c_str());
+ return;
+ }
+
const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke");
const DexFile::CodeItem* code_item = method->GetCodeItem();
uint16_t num_regs;