Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you crash a JVM?

Tags:

java

jvm

I was reading a book on programming skills wherein the author asks the interviewee, "How do you crash a JVM?" I thought that you could do so by writing an infinite for-loop that would eventually use up all the memory.

Anybody has any idea?

like image 658
Shivasubramanian A Avatar asked Sep 15 '08 18:09

Shivasubramanian A


People also ask

How do I investigate JVM crash?

Try running the application without the YJP agent to see if you can still reproduce the crash. Generally, JVM crashes are pretty hard to diagnose. They could happen due to a bug in some JNI code or in the JRE itself. If you suspect the latter, it may be worth submitting a bug report to Oracle.

Why does the JVM crash with a core dump?

Common causes of JVM Crash Running out of native memory. This is caused when native memory is exhausted, read more about native memory allocation here. Segmentation faults. These are caused by a program trying to read or write an illegal memory location.

Where are JVM crash logs?

Viewing Java Virtual Machine crash logs JVM crash log files are named hs_err_pid*. log, with the process id of the JVM that crashed, and are placed in the Micro-Manager folder.

How do I stop JVM from crashing?

Reduce the Java heap size. The Java heap is only a certain part of the total memory used by the JVM. If the Java heap is significantly larger, JVM can run out of virtual memory while compiling methods or when native libraries are loaded. Try lowering the maximum heap size to avoid this error.


10 Answers

I wouldn't call throwing an OutOfMemoryError or StackOverflowError a crash. These are just normal exceptions. To really crash a VM there are 3 ways:

  1. Use JNI and crash in the native code.
  2. If no security manager is installed you can use reflection to crash the VM. This is VM specific, but normally a VM stores a bunch of pointers to native resources in private fields (e.g. a pointer to the native thread object is stored in a long field in java.lang.Thread). Just change them via reflection and the VM will crash sooner or later.
  3. All VMs have bugs, so you just have to trigger one.

For the last method I have a short example, which will crash a Sun Hotspot VM quiet nicely:

public class Crash {
    public static void main(String[] args) {
        Object[] o = null;

        while (true) {
            o = new Object[] {o};
        }
    }
}

This leads to a stack overflow in the GC so you will get no StackOverflowError but a real crash including a hs_err* file.

like image 86
ralfs Avatar answered Sep 17 '22 00:09

ralfs


JNI. In fact, with JNI, crashing is the default mode of operation. You have to work extra hard to get it not to crash.

like image 21
Dan Dyer Avatar answered Sep 17 '22 00:09

Dan Dyer


Use this:

import sun.misc.Unsafe;

public class Crash {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    public static void crash() {
        unsafe.putAddress(0, 0);
    }
    public static void main(String[] args) {
        crash();
    }
}

This class must be on the boot classpath because it is using trusted code,so run like this:

java -Xbootclasspath/p:. Crash

EDIT: Simplified version with pushy's suggestion:

Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
unsafe.putAddress(0, 0);
like image 21
Dave Griffiths Avatar answered Sep 18 '22 00:09

Dave Griffiths


I came here because I also ran into this question in The Passionate Programmer, by Chad Fowler. For those who don't have access to a copy, the question is framed as a kind of filter/test for candidates interviewing for a position requiring "really good Java programmers."

Specifically, he asks:

How would you write a program, in pure Java, that would cause the Java Virtual Machine to crash?

I've programmed in Java for over 15 years, and I found this question to be both puzzling and unfair. As others have pointed out, Java, as a managed language, is specifically designed not to crash. Of course there are always JVM bugs, but:

  1. After 15+ years of production-level JREs, it's rare.
  2. Any such bugs are likely to be patched in the next release, so how likely are you as a programmer to run into and recall the details of the current set of JRE show-stoppers?

As others have mentioned, some native code via JNI is a sure way to crash a JRE. But the author specifically mentioned in pure Java, so that's out.

Another option would be to feed the JRE bogus byte codes; it's easy enough to dump some garbage binary data to a .class file, and ask the JRE to run it:

$ echo 'crap crap crap' > crap.class
$ java crap
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1668440432 in class file crap

Does that count? I mean the JRE itself hasn't crashed; it properly detected the bogus code, reported it, and exited.

This leaves us with the most obvious kinds of solutions such as blowing the stack via recursion, running out of heap memory via object allocations, or simply throwing RuntimeException. But this just causes the JRE to exit with a StackOverflowError or similar exception, which, again is not really a crash.

So what's left? I'd really love to hear what the author really had in mind as a proper solution.

Update: Chad Fowler responded here.

PS: it's an otherwise great book. I picked it up for moral support while learning Ruby.

like image 45
George Armhold Avatar answered Sep 18 '22 00:09

George Armhold


Last time I tried this would do it:

public class Recur {
    public static void main(String[] argv) {
        try {
            recur();
        }
        catch (Error e) {
            System.out.println(e.toString());
        }
        System.out.println("Ended normally");
    }
    static void recur() {
        Object[] o = null;
        try {
            while(true) {
                Object[] newO = new Object[1];
                newO[0] = o;
                o = newO;
            }
        }
        finally {
            recur();
        }
    }
}

First part of generated log file:

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x000000006dad5c3d, pid=6752, tid=1996
#
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode windows-amd64)
# Problematic frame:
# V  [jvm.dll+0x2e5c3d]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x00000000014c6000):  VMThread [stack: 0x0000000049810000,0x0000000049910000] [id=1996]

siginfo: ExceptionCode=0xc00000fd, ExceptionInformation=0x0000000000000001 0x0000000049813fe8 

Registers:
EAX=0x000000006dc83090, EBX=0x000000003680f400, ECX=0x0000000005d40ce8, EDX=0x000000003680f400
ESP=0x0000000049813ff0, EBP=0x00000000013f2df0, ESI=0x00000000013f0e40, EDI=0x000000003680f400
EIP=0x000000006dad5c3d, EFLAGS=0x0000000000010206
like image 34
Hot Licks Avatar answered Sep 18 '22 00:09

Hot Licks


This code will crash the JVM in nasty ways

import sun.dc.pr.PathDasher; 

public class Crash
{
     public static void main(String[] args)
     {    
        PathDasher dasher = new PathDasher(null) ;
     }
}
like image 21
Rob Mayhew Avatar answered Sep 20 '22 00:09

Rob Mayhew


A perfect JVM implementation will never crash.

To crash a JVM, aside from JNI, you need to find a bug in the VM itself. An infinite loop just consumes CPU. Infinitely allocating memory should just cause OutOfMemoryError's in a well built JVM. This would probably cause problems for other threads, but a good JVM still should not crash.

If you can find a bug in the source code of the VM, and for example cause a segmentation fault in the memory usage of the implementation of the VM, then you can actually crash it.

like image 36
Dave L. Avatar answered Sep 20 '22 00:09

Dave L.


If you want to crash JVM - use the following in Sun JDK 1.6_23 or below:

Double.parseDouble("2.2250738585072012e-308");

This is due to a bug in Sun JDK - also found in OpenJDK. This is fixed from Oracle JDK 1.6_24 onwards.

like image 44
Prabath Siriwardena Avatar answered Sep 21 '22 00:09

Prabath Siriwardena


Depends on what you mean by crash.

You can do an infinite recursion to make it run out of stack space, but that'll crash "gracefully". You'll get an exception, but the JVM itself will be handling everything.

You can also use JNI to call native code. If you don't do it just right then you can make it crash hard. Debugging those crashes is "fun" (trust me, I had to write a big C++ DLL that we call from a signed java applet). :)

like image 32
Herms Avatar answered Sep 19 '22 00:09

Herms


The closest thing to a single "answer" is System.exit() which terminates the JVM immediately without proper cleanup. But apart from that, native code and resource exhaustion are the most likely answers. Alternatively you can go looking on Sun's bug tracker for bugs in your version of the JVM, some of which allow for repeatable crash scenarios. We used to get semi-regular crashes when approaching the 4 Gb memory limit under the 32-bit versions (we generally use 64-bit now).

like image 32
Leigh Caldwell Avatar answered Sep 18 '22 00:09

Leigh Caldwell