Skip to content

Instantly share code, notes, and snippets.

@shipilev
Created March 25, 2020 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shipilev/0ba1490d64c14645ee903fc695e931b5 to your computer and use it in GitHub Desktop.
Save shipilev/0ba1490d64c14645ee903fc695e931b5 to your computer and use it in GitHub Desktop.
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
public class Play {
public static void main(String[] args) throws Exception {
AddressExtractor ae = new AddressExtractor();
Field pvField = AddressExtractor.class.getDeclaredField("pointerValue");
Field type = Field.class.getDeclaredField("type");
type.setAccessible(true);
type.set(pvField, Object.class);
// Setting is relatively safe:
Dummy dummy = new Dummy();
pvField.set(ae, dummy);
System.out.println(Long.toHexString(ae.pointerValue));
// Getting is NOT!
ae.pointerValue = 0xDEADBEEF;
// Used to be this in example:
//System.out.println(pvField.get(ae) == foo);
// It is the same as getting Object in the local.
// ...and if GC happens in the middle:
Object o = pvField.get(ae);
System.gc(); // SEGV, because "o" is not actually the object
System.out.println(o == dummy);
System.in.read();
}
}
class AddressExtractor {
public long pointerValue;
}
class Dummy {
public long value;
}
/*
$ ~/Install/jdk8u232/bin/java Play
b002c00c
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f85878c563c, pid=3437, tid=0x00007f85854af700
#
# JRE version: OpenJDK Runtime Environment (8.0) (build 1.8.0-builds.shipilev.net-openjdk-jdk8-b24-20191015-jdk8u232-b09:jdk8u232-ga)
# Java VM: OpenJDK 64-Bit Server VM (25.71-b24-20191015-jdk8u232-09:jdk8u232-ga mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0x91363c] PSRootsClosure<false>::do_oop(oopDesc**)+0x1c
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/shade/temp/reflect/hs_err_pid3437.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)
$ ~/Install/jdk11.0.6-ea/bin/java Play
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by Play (file:/home/shade/temp/reflect/) to field java.lang.reflect.Field.type
WARNING: Please consider reporting this to the maintainers of Play
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Exception in thread "main" java.lang.IllegalArgumentException: Can not set long field AddressExtractor.pointerValue to Dummy
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeLongFieldAccessorImpl.set(UnsafeLongFieldAccessorImpl.java:102)
at java.base/java.lang.reflect.Field.set(Field.java:780)
at Play.main(Play.java:14)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment