fix method interception bug

When we intercept a method (i.e. when the VM wants to run its own code
instead of whatever the classpath provides for that method), we make a
clone of the original method so we can later call it from the
intercepting code if appropriate.  We also set the ACC_NATIVE flag on
the original method to ensure that our intercepting code is always
used in preference to the classpath version.  However, we need to set
that flag *after* we make the clone, or else the clone will also have
the ACC_NATIVE flag set, which is not what we want.

We never noticed this before because classpath versions of all the
methods we intercept as of Java 7 are either native or are never
called from their VM-specified replacements.  However, some of those
native methods are non-native in later versions of Java, so the bug
has become apparent.
This commit is contained in:
Joel Dice 2015-01-12 09:54:11 -07:00
parent f6e7a29f09
commit 4509e29abb

View File

@ -611,11 +611,11 @@ void intercept(Thread* t,
if (m) {
PROTECT(t, m);
m->flags() |= ACC_NATIVE;
if (updateRuntimeData) {
GcMethod* clone = methodClone(t, m);
m->flags() |= ACC_NATIVE;
// make clone private to prevent vtable updates at compilation
// time. Otherwise, our interception might be bypassed by calls
// through the vtable.
@ -628,6 +628,8 @@ void intercept(Thread* t,
GcMethodRuntimeData* runtimeData = getMethodRuntimeData(t, m);
runtimeData->setNative(t, native->as<GcNative>(t));
} else {
m->flags() |= ACC_NATIVE;
}
} else {
// If we can't find the method, just ignore it, since ProGuard may