3

I have seen the question like how-do-you-crash-a-jvm and shortest-code-that-raises-a-sigsegv
There are some java code to produce SIGSEGV like:

final Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
final Unsafe unsafe = unsafeConstructor.newInstance();
System.out.println(unsafe.getAddress(0));

and it produces a SIGSEGV typed V(VM frame).

# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V  [jvm.dll+0x1e2440]

And there is Crash in Compiled Code according to https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/crashes001.html.

I wonder if there anyway to produce a typed J segmentation fault.
And I have seen some lib issue like JVM crash.(So it indicates that can be manually produced?)

fairjm
  • 1,115
  • 12
  • 26
  • 2
    What is "typed J segmentation fault"? – talex Dec 05 '18 at 09:14
  • @talex `Crash in Compiled Code` .It means crash happened in java frame(The example V is VM fame). – fairjm Dec 05 '18 at 09:33
  • There is no java code that can produce it. You have to corrupt some internal structures using native code or unsafe. – talex Dec 05 '18 at 09:47
  • @talex Thx~ Using Unsafe to produce is ok for the question.Other codes using Unsafe just produce crash in VM frame so I want to see how can Unsafe be used to produce crash in java frame. Before asking, I tried to use Unsafe to assign int field an object instance(or other different types) and get it using getter...But the code worked fine without any error... – fairjm Dec 05 '18 at 09:53
  • You have to know internal structure of JVM to understand how to do it. I don't posses such knowledge. – talex Dec 05 '18 at 09:55
  • A crash on a `J` method indicates a bug in the JVM or a corruption of the JVM. This is much harder to recreate. – Peter Lawrey Dec 05 '18 at 11:08
  • @talex Thx anyway :) – fairjm Dec 05 '18 at 12:21
  • @PeterLawrey Yes, and I found one from slideshare https://www.slideshare.net/AndreiPangin/do-we-need-unsafe-in-java (p53) but can't reproduce directly (Put random buffer size and addr get V frame) – fairjm Dec 05 '18 at 12:26
  • Can you clarify the problem? – Sapphire_Brick Jun 16 '20 at 22:17

2 Answers2

8

Here is a program that reproduces a crash in compiled code.

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class Crash extends Thread {
    static volatile Object obj = 0;

    public static void main(String[] args) throws Exception {
        new Crash().start();

        // Give some time to compile run() method
        Thread.sleep(2000);

        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);

        // Overwrite Object's class field, so that 'instanceof' cannot work
        unsafe.putInt(obj, 8L, -1);
    }

    public void run() {
        while (!(obj instanceof Runnable)) {
            // Loop until crash
        }
    }
}

So how it works. (Or it would be right to say "how it doesn't work" :)

  1. Run a thread with an infinite loop. This loop is obviously "hot", so the method gets JIT-compiled.
  2. instanceof check cannot be optimized away, since obj is volatile.
  3. After some time we spoil obj header by writing garbage to its class field at offset #8.
  4. This breaks the compiled code, because instanceof check relies on the object class.

And here what we'll get.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000368b6ad, pid=9660, tid=0x00000000000032f0
#
# JRE version: Java(TM) SE Runtime Environment (8.0_192-b12) (build 1.8.0_192-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.192-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# J 38% C2 Crash.run()V (13 bytes) @ 0x000000000368b6ad [0x000000000368b640+0x6d]
#
apangin
  • 92,924
  • 10
  • 193
  • 247
3

When the JVM crashes like this, it shows you the actual stack trace after inlining. This means methods which have been inlined don't appear.

What you can do is run a test where this code is warmed up to the point where Unsafe is inlined, then you can trigger a crash which will appear to come from a Java method, however, it's just that the real cause has been inlined.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130