Frage

Ich habe ein Buch über Programmierkenntnisse zu lesen, wobei der Autor die Interviewten fragt: „Wie kann man eine JVM abstürzen?“ Ich dachte, dass Sie durch das Schreiben eine unendliche for-Schleife tun könnte, die schließlich den gesamten Speicher verwenden würde.

Wer hat eine Idee?

War es hilfreich?

Lösung

Die nächste Sache zu einem einzigen „Antwort“ ist System.exit(), die die JVM sofort ohne ordnungsgemäße Bereinigung beendet. Aber abgesehen davon, nativen Code und Ressourcenerschöpfung sind die wahrscheinlichsten Antworten. Alternativ können Sie in Ihrer Version der JVM für Fehler auf der Sun Bug-Tracker gehen suchen, von denen einige für wiederholbare Crash-Szenarien ermöglichen. Wir verwenden Halb regelmäßige Abstürze zu erhalten, wenn die 4 Gb Speichergrenze unter den 32-Bit-Versionen nähern (wir verwenden in der Regel 64-Bit-jetzt).

Andere Tipps

ich nennen würde keine OutOfMemoryError oder Stackoverflow einen Absturz zu werfen. Dies sind nur normale Ausnahmen. Um wirklich eine VM zum Absturz gibt es 3 Möglichkeiten:

  1. Verwenden Sie JNI und Absturz in den nativen Code.
  2. Wenn kein Sicherheitsmanager installiert ist, Sie Reflektion verwenden, um die VM zum Absturz bringen. Dies ist VM spezifisch, aber in der Regel einer VM speichert eine Reihe von Zeigern auf einheimische Ressourcen in privaten Bereichen (zum Beispiel ein Zeiger auf das native Thread-Objekt wird in einem langen Feld in java.lang.Thread gespeichert). ändern sie nur durch Reflexion und die VM stürzt früher oder später.
  3. Alle VMs haben Fehler, so dass Sie nur eine auslösen müssen.

Für die letzte Methode, die ich ein kurzes Beispiel haben, die eine Sun Hotspot VM ruhig schön abstürzen:

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

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

Dies führt zu einem Stack-Überlauf in der GC, so dass Sie keine Stackoverflow aber einen wirklichen Absturz mit einer hs_err * Datei erhalten.

JNI . In der Tat, mit JNI, Krachen ist der Standardbetriebsmodus. Sie haben extra hart zu arbeiten, um es zu bekommen nicht zum Absturz bringen.

verwenden:

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();
    }
}

Diese Klasse auf dem Boot-Classpath sein muss, weil es vertrauenswürdiger Code verwendet, so laufen wie folgt aus:

  

java -Xbootclasspath / p :. Crash

Ich bin hierher gekommen, weil ich auch in dieser Frage in The Passionate Programmer lief von Chad Fowler. Für diejenigen, die keinen Zugriff auf eine Kopie haben, wird die Frage als eine Art Filter / Test eingerahmt für Kandidaten für eine Position zu interviewen erfordern „wirklich guten Java-Programmierer.“

Im Einzelnen fragt er:

  

Wie würden Sie ein Programm, in reinem Java zu schreiben, das wäre die Java Virtual Machine zum Absturz bringen?

Ich habe seit über 15 Jahren in Java programmiert, und ich fand diese Frage ebenso rätselhaft und ungerecht. Wie andere haben darauf hingewiesen, Java, als Sprache verwaltet wird, ist speziell auf nicht abstürzen . Natürlich gibt es immer JVM Fehler, aber:

  1. Nach 15+ Jahren Produktionsebene JREs, es ist selten.
  2. Solche Fehler sind wahrscheinlich in der nächsten Version gepatcht werden, so wie Sie wahrscheinlich als Programmierer in laufen und die Details des aktuellen Satzes von JRE Show-Stopper zu erinnern?

Wie andere erwähnt haben, einige nativen Code über JNI ist ein sicherer Weg, um eine JRE zum Absturz bringen. Aber der Autor ausdrücklich erwähnt in reinem Java , das ist also aus.

Eine andere Möglichkeit wäre es, die JRE falsche Byte-Codes zuzuführen; es ist leicht genug, um einige Müll binäre Daten in eine .class-Datei zu entleeren, und fragen Sie die JRE, um sie auszuführen:

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

Zählt das? Ich meine, die JRE selbst nicht abgestürzt ist; detektiert richtig den falschen Code, berichtet er, und verlassen.

Dies lässt uns mit den offensichtlichsten Arten von Lösungen wie den Stapel über Rekursion bläst, über das Objekt Zuweisungen aus Heap-Speicher ausgeführt wird, oder einfach RuntimeException werfen. Aber dies bewirkt, dass nur die JRE mit einem StackOverflowError oder ähnlicher Ausnahme zu verlassen, was, wieder nicht wirklich einen Absturz .

Also, was bleibt? Ich würde wirklich gerne hören, was der Autor wirklich im Sinne, als eine angemessene Lösung hatte.

Aktualisieren :. Chad Fowler hier reagiert

PS: es ist ein sonst großes Buch. Ich nahm es für die moralische Unterstützung, während Ruby-Lernen.

Dieser Code wird die JVM in fiese Weise abstürzen

import sun.dc.pr.PathDasher; 

public class Crash
{
     public static void main(String[] args)
     {    
        PathDasher dasher = new PathDasher(null) ;
     }
}

Das letzte Mal habe ich versucht, das es tun würde:

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();
        }
    }
}

Der erste Teil der erzeugten Protokolldatei:

#
# 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

Eine perfekte JVM Implementierung wird niemals zum Absturz bringen.

eine JVM zum Absturz zu bringen, abgesehen von JNI, benötigen Sie einen Fehler in dem VM selbst zu finden. Eine Endlosschleife verbraucht nur CPU. Stufenlos Zuweisung Speicher sollten nur dazu führen, OutOfMemoryError die in einem gut gebauten JVM. Dies würde wahrscheinlich zu Problemen führt, für andere Threads, aber eine gute JVM soll noch nicht zum Absturz bringen.

Wenn Sie einen Fehler im Quellcode der VM finden, und zum Beispiel eines Segmentation Fault in der Speichernutzung der Implementierung der VM verursachen, dann können Sie es tatsächlich zum Absturz bringen.

Wenn Sie JVM abstürzen - verwenden Sie die folgende in Sun JDK 1.6_23 oder unter:

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

Dies ist auf einen Fehler in Sun JDK - auch in OpenJDK gefunden. Dies ist fest von Oracle JDK 1.6_24 ab.

Abhängig von, was Sie durch Absturz bedeuten.

Sie können eine unendliche Rekursion tun, um es aus Stapelspeicher laufen zu lassen, aber das wird abstürzen „anmutig“. Sie erhalten eine Ausnahme, aber die JVM selbst wird alles handhaben.

Sie können JNI auch nativen Code aufzurufen verwenden. Wenn Sie es nicht nur richtig machen, dann können Sie machen es schwer abstürzen. Debuggen diese Abstürze ist „Spaß“ (glauben Sie mir, ich musste eine große C ++ DLL schreiben, die wir von einem signierten Java-Applet aufrufen). :)

Das Buch Java Virtual Machine von Jon Meyer hat ein Beispiel für eine Reihe von Bytecode-Anweisungen, die die JVM auf Core-Dump verursacht. Ich kann nicht mein Exemplar dieses Buches finden. Wenn jemand da man bitte schauen sie hat aus und veröffentlichen die Antwort.

auf winxpsp2 w / WMP10 jre6.0_7

Desktop.open (uriToAviOrMpgFile)

Dies bewirkt einen erzeugte Thread eine abgefangene Throwable zu werfen und stürzt Hotspot

YMMV

Gebrochene Hardware kann ein beliebiges Programm zum Absturz bringen. Ich hatte einmal einen App Absturz reproduzierbar auf einer bestimmte Maschine, während fein mit der exakt gleichen Konfiguration auf anderen Maschinen ausgeführt werden. Es stellte sich heraus, dass Maschine defekt RAM hatte.

kürzester Weg:)

public class Crash
{
    public static void main(String[] args)
    {
        main(args);
    }
}

Kein Absturz, aber näher an einem Crash als die akzeptierte Antwort der Verwendung System.exit

Sie können die JVM halt durch den Aufruf

Runtime.getRuntime().halt( status )

Nach der Dokumentation: -

  

„Diese Methode verursacht keine Abschaltung Haken gestartet werden und läuft nicht uninvoked Finalizers wenn Finalisierung-on-Ausgang aktiviert wurde“.

Hier ist eine detaillierte Erklärung, was JVM Core-Dump verursacht (das heißt crash): http://kb.adobe.com/selfservice/viewContent.do?externalId= tn_17534

Wenn Sie einen Absturz als Prozess abbrechen wegen einer nicht behandelten Situation (dh keine Java Exception oder Error) definieren, dann kann dies nicht aus Java getan werden (es sei denn, Sie über die Berechtigung der sun.misc.Unsafe Klasse zu verwenden) . Das ist der ganze Sinn des verwalteten Code.

Typische Abstürze in nativen Code passieren durch de-Referenzierung Zeiger auf falsche Speicherbereiche (null-Adresse oder missaligned). Eine andere Quelle könnte illegal Maschinenbefehle sein (Opcodes) oder nicht behandelte Signale aus der Bibliothek oder Kernel-Anrufe. Beide können ausgelöst werden, wenn die JVM oder die Systembibliotheken haben Fehler.

Zum Beispiel JITed (generiert) code, nativen Methoden oder Systemaufrufe (Grafiktreiber) Probleme, die zu echten Abstürze haben kann (es war durchaus üblich, einen Absturz zu erhalten, wenn Sie ZIP-Funktionen verwendet und sie liefen aus der Erinnerung). In diesen Fällen tritt die Crash-Handler der JVM in und Dumps den Zustand. Es könnte auch ein O Core-Datei (Dr. Watson auf Windows und Core-Dump auf * nichts) erzeugen.

Unter Linux / Unix können Sie easyly eine JVM zum Absturz bringen, indem er ein Signal an den laufenden Prozess zu senden. Hinweis: Sie sollten nicht SIGSEGV dafür verwenden, da Hotspot dieses Signal auffängt und wieder wirft sie als Nullpointer in den meisten Orten. So ist es besser, einen SIGBUS zum Beispiel senden.

Wenn Sie wollen, so zu tun, haben Sie über genügend Arbeitsspeicher ausgeführt Sie tun können,

public static void main(String[] args) {
    throw new OutOfmemoryError();
}

Ich kenne ein paar Weg, um die JVM-Dump eine Fehlerdatei verursachen durch den Aufruf von nativen Methoden (solche, die eingebaut sind), aber es ist wahrscheinlich am besten Sie nicht wissen, wie dies zu tun. ;)

JNI ist eine große Quelle von Abstürzen. Sie können auch die JVMTI Schnittstelle zum Absturz verwenden, da die in C / C ++ als auch geschrieben werden muss.

Wenn Sie einen Thread-Prozess erstellen, die unendlich mehr Threads laicht (die mehr Threads erzeugen, die ...) Sie schließlich einen Stapelüberlauf Fehler in der JVM selbst führen.

public class Crash {
    public static void main(String[] args) {

        Runnable[] arr = new Runnable[1];
        arr[0] = () -> {

            while (true) {
                new Thread(arr[0]).start();
            }
        };

        arr[0].run();
    }
}

Das gab mir den Ausgang (nach 5 Minuten, sehen Sie Ihre ram)

An unrecoverable stack overflow has occurred.
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x0000000070e53ed7, pid=12840, tid=0x0000000000101078
#
# JRE version: Java(TM) SE Runtime Environment (8.0_144-b01) (build 1.8.0_144-b01)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# 

Kürzeste? Verwenden Robot-Klasse CTRL + BREAK auslösen. Ich entdeckte, als ich versuchte, mein Programm ohne Konsole schließen (es hatte keine ‚exit‘ Funktionalität).

zu schließen

Ich mache es jetzt, aber nicht ganz sicher, wie ... :-) JVM (und meine app) manchmal nur ganz verschwinden. Keine Fehler geworfen, nichts protokolliert. Geht von der Arbeit bis gar nicht sofort ohne Warnung ausgeführt wird.

Enthält diese zählen?

long pid = ProcessHandle.current().pid();
try { Runtime.getRuntime().exec("kill -9 "+pid); } catch (Exception e) {}

Es funktioniert nur für Linux und Java 9.

Aus irgendeinem Grund, den ich nicht bekommen, ist ProcessHandle.current().destroyForcibly(); nicht die JVM töten und wirft java.lang.IllegalStateException mit der Meldung des aktuellen Prozesses zerstören nicht erlaubt .

Wenn Sie diese unendliche for-Schleife zu einem rekursiven Aufruf der gleichen Funktion ändern, dann würden Sie einen Stapelüberlauf Ausnahme erhalten:

public static void main(String[] args) {
    causeStackOverflow();
}

public void causeStackOverflow() {
    causeStackOverflow();
}

Wenn ein ‚Crash‘ etwas ist, dass das JVM / Programm von normaler Beendigung unterbricht, dann wird eine Un-behandelte Ausnahme könnte dies tun.

public static void main(String args[]){
   int i = 1/0;
   System.out.print(i); // This part will not be executed due to above  unhandled exception
  }

Also, es hängt davon ab, welche Art von CRASH?!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top