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-loo
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) ;
}
}
The book Java Virtual Machine by Jon Meyer has an example of a series of bytecode instructions that caused the JVM to core dump. I can't find my copy of this book. If anyone out there has one please look it up and post the answer.
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:
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.
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
If you want to pretend you have run out of memory you can do
public static void main(String[] args) {
throw new OutOfmemoryError();
}
I know a couple of way to cause the JVM dump an error file by calling native methods (ones which are built in), but its probably best you not know how to do this. ;)
JNI. In fact, with JNI, crashing is the default mode of operation. You have to work extra hard to get it not to crash.