SAP / project-fontus

Dynamic tainting framework for Java applications leveraging on-the-fly bytecode rewriting.
Apache License 2.0
6 stars 2 forks source link

Incompatibility with Github Jamm, a memory meter #28

Open leeN opened 3 weeks ago

leeN commented 3 weeks ago

Github jamm is a memory meter application which is used in the dacapo benchmarking suite. It does some rather insane stuff with Unsafe to directly access properties of a String.

Field field = String.class.getDeclaredField("value");
Optional<MethodHandle> mayBeTrySetAccessible = MethodHandleUtils.mayBeMethodHandle(Field.class, "trySetAccessible"); // Added in Java 9
if (mayBeTrySetAccessible.isPresent()) {
    // Base on the JMH benchmarks, Unsafe is faster than using a MethodHandle so we try to use Unsafe first and default to reflection if it is unavailable.  
    Unsafe unsafe = VM.getUnsafe();
    if (unsafe == null) {
        if ((boolean) mayBeTrySetAccessible.get().invoke(field)) {
            return new PlainReflectionStringMeter(methodHandle(field));
        }
        throw new CannotAccessFieldException("The value of the 'value' field from java.lang.String"
                                              + " cannot be retrieved as the field cannot be made accessible and Unsafe is unavailable");
    }

    long valueFieldOffset = unsafe.objectFieldOffset(field);
    return new UnsafeStringMeter(unsafe, valueFieldOffset);
}

As we exchange String with IASString here, the code tries to access a property of IASString (i.e., the value char array) that does not exist.

Fixing this is fairly involved, and probably needs a special case catching such attempts.