Abfangen eines externen nativen Code Crash

Alles zu NetBeans als RCP-Platform

Moderator: wegus

Antworten
WeserLinux
Beiträge: 89
Registriert: 16.03.2012, 10:46
Wohnort: Niedersachsen

Abfangen eines externen nativen Code Crash

Beitrag von WeserLinux » 19.12.2012, 13:42

Hallo Zusammen !

Leider konnte ich bisher keine Lösung im Internet finden, so frage ich mal in die Runde.

Meine Netbeans 7.0.1 Applikation nutzt das JNA API (Java Native Access) um eine externe C-Bibliothek auszuwerten. Während des Zugriffs kommt es zu einem Crash in der C-Routine, die zum kompletten Absturz der JVM führt. Es erscheint die bekannte Ausgabe
# The crash happened outside the Java Virtual Machine in native code.
Da Exceptions keine Wirkung zeigen, hat jemand eine Idee, ob und wie man den JVM Absturz verhindern kann?


Ich habe mal ein sehr kurzes Beispiel in Netbeans 7.0.1 nachgebaut, um diesen Crash der JVM zu simulieren. Zuerst die Java Main Klasse

Code: Alles auswählen

import java.io.File;

public class RunCLibInJava {

    public static void main(String[] args) {

        String libPath = "$PATH_TO_LIB/badlib.so";
        RunCCode runCode = new RunCCode();

        runCode.setLibFile(new File(libPath));
        runCode.attach();
    }
}
und die folgenden Klassen zum Verarbeiten und Laden der Bibliothek badlib.so

Code: Alles auswählen

import java.io.File;

public class RunCCode {

    private MyInterface nativeFunctions;
    private File libFile;

    public void attach() {
        if (nativeFunctions == null) {
            nativeFunctions = NativeLibrary.load(libFile);

            nativeFunctions.run_main();
        }
    }

    public void setLibFile(File libFile) {
        this.libFile = libFile;
    }
}

Code: Alles auswählen

public interface MyInterface {

    void run_main();
}

Code: Alles auswählen

import java.io.File;
import com.sun.jna.Library;

public class NativeLibrary {

    private interface NativeInterface extends MyInterface, Library {
    }

    public static MyInterface load(File libFile) {
        return NativeHelper.load(libFile, NativeInterface.class);
    }
}

Code: Alles auswählen

import java.io.File;
import com.sun.jna.Library;
import com.sun.jna.Native;

public class NativeHelper {

    @SuppressWarnings("unchecked")
    public static <T extends Library> T load(File libFile, Class<T> clazz) {
        return (T) Native.loadLibrary(libFile.getPath(), clazz);
    }
}
Die C-Bibliothek besteht nur aus einer Objekt Datei des folgenden C-Codes

Code: Alles auswählen

#include <stdio.h>

int run_main()
{
  printf ("%s", 'a');
}
und ist mit dem gcc gebaut worden. Das Ausführen der Routine run_main() führt zum seqmentation fault und damit zum unschönen Absturz der JVM.


Gruss

Death89
Beiträge: 21
Registriert: 20.12.2011, 12:25

Re: Abfangen eines externen nativen Code Crash

Beitrag von Death89 » 19.12.2012, 14:48

Hast du schon versucht in die main-Methode try catch einzubauen:

Code: Alles auswählen

try{
 runCode.attach();
}
catch {}
Dann müsste eigentlich alles abgefangen werden...

Benutzeravatar
Olek77
Beiträge: 669
Registriert: 21.03.2009, 13:09

Re: Abfangen eines externen nativen Code Crash

Beitrag von Olek77 » 19.12.2012, 19:42

Hi,

Schau mal hier :
https://github.com/twall/jna

Dort findest du einige Beispiele und auch ein QaA, wo einige Absturzszenarien erklärt werden.

Gruß,

Olek
- Netbeans Certified Associate -

WeserLinux
Beiträge: 89
Registriert: 16.03.2012, 10:46
Wohnort: Niedersachsen

Re: Abfangen eines externen nativen Code Crash

Beitrag von WeserLinux » 20.12.2012, 10:03

@Death89:
Das ist ja gerade das Interessante, die try-catch Mechanismen reagieren hier leider nicht mehr wie gewünscht. Dein Vorschlag ändert leider nichts, die JVM stürzt ab.

@Olek77
Vielen Dank. Ich schaue da mal rein.

Benutzeravatar
Olek77
Beiträge: 669
Registriert: 21.03.2009, 13:09

Re: Abfangen eines externen nativen Code Crash

Beitrag von Olek77 » 20.12.2012, 11:46

Re,

Die try&catch Blöcke können nicht funktionieren, weil sie nicht den Fehler im nativen code "überbrücken" können.

Das hier habe ich von der JNA-Seite :

VM Crash Protection
It is not uncommon when defining a new library and writing tests to encounter memory access errors which crash the VM. These are often caused by improper mappings or invalid arguments passed to the native library. To generate Java errors instead of crashing the VM, call Native.setProtected(true). Not all platforms support this protection; if not, the value of Native.isProtected() will remain false.


Gruß,

Olek
- Netbeans Certified Associate -

WeserLinux
Beiträge: 89
Registriert: 16.03.2012, 10:46
Wohnort: Niedersachsen

Re: Abfangen eines externen nativen Code Crash

Beitrag von WeserLinux » 20.12.2012, 14:32

Hallo Olek77 !

Wie Du gesagt hast, der Text zu VM Crash Protection ist wirklich hilfreich. Es kommt auf die Methode

Code: Alles auswählen

Native.setProtected(true);
an, die bei mir unter Linux auch einen guten Dienst tut. Packt man jetzt den C-Bibliotheken-Aufruf in der Klasse RunCCode noch in einen try-catch Block in der Form

Code: Alles auswählen

try {
        nativeFunctions.run_main();
} catch (Throwable t) {
        System.out.println("Problem beim C-Code");
} finally {
        System.out.println("weiter gehts");
}
sieht es doch tatsächlich so aus, als bleibt das System am Leben und setzt sich fort.

Das werde ich jetzt mal an der großen Applikation ausprobieren. Vielen Dank erst einmal !

Antworten