komisches JNI-Problem

roxX0r

Mitglied
Hallo,

mein Java Programm nutzt eine in C geschriebene DLL, um auf die win32 API zuzugreifen. Beispielsweise für systemweite Hotkeys oder Maushooks. Soweit so gut. Eigentlich läuft alles prima, nur es kommt ab und zu vor (wenn mein Programm länger läuft), dass das Programm crasht. Danach wird ein Error Log generiert. In dem steht sowas drin:

# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x027a5a4c, pid=4276, tid=4408
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b23 mixed mode, sharing windows-x86)
# Problematic frame:
# J ConstantClasses.NativeFunctions.PressActionButton(ILjava/lang/String;I)V
...
...

Darunter noch jede Menge Infos, Registers, Stacks, Instructions.. Alles Dinge die mir nichts sagen. Ich denke nicht, dass ich die Ursache für diese Crashes rausbekomme. Ich habe ganz normalen C Code drin und es funktioniert ja auch eine gewisse Zeit. Manchmal Stunden, manchmal nur ne halbe... ganz unterschiedlich. Irgendwann scheint es ne Zugriffsverletzung zu geben ...

Meine Frage ist nun, ob jemand eine Idee hat, wie ich diesen "crash" vielleicht abfangen kann?
Oder vielleicht doch nach der Ursache suchen, aber ich weiß nicht, wie ich da anfangen soll... bin für jeden Tipp dankbar!
 
Das ist ein Crash der JVM und somit nicht abfangbar! Da du JNI verwendest liegt es mit ziemlich hoher Wahrscheinlichkeit an deinem C-Code. Der kann die JVM ziemlich leicht zum Absturz bringen, wenn da ein Fehler drin ist!

Evtl. hilfts, wenn du en C-Code hier mal posten kannst, ODER in einem C-Forum, wenn er zu umfangreich ist.
 
hier ist mal eine Funktion, die ab und zu den Crash verursacht.

Code:
char txt[100]; //globale Variable

BOOL FindSomething(HWND hWnd, long lParam) {
    char cFind[] = "findstring1";
    char cFind2[] = "findstring2";

    if (SendMessage(hWnd, WM_GETTEXT, (WPARAM) 100, (LPARAM) txt) == 0) return TRUE;
    if (strstr(txt, cFind) != NULL || strstr(txt, cFind2) != NULL) {
        return FALSE;
    }
    return TRUE;
}

JNIEXPORT jstring JNICALL Java_ConstantClasses_NativeFunctions_getSomthingFromNative(JNIEnv *env, jobject obj, jint handle) {
    HWND h;
    char ret[100];
    int i = 0;
    if (handle == -1) h = GetForegroundWindow();
    else h = (HWND) handle;


    EnumChildWindows(h, (WNDENUMPROC) FindSomthing, 0);
    for (i = 0; i < 100; i++) ret[i] = txt[i];
    jstring cStr = (*env)->NewStringUTF(env, ret);
    return cStr;
}

Das einzige was hier gemacht wird ist die Rückgabe eines Strings... aber ich hab keine Ahnung wo da ne Zugriffsverletzung ab und zu mal auftreten soll ...
 
Hmm wozu brauchst du eigentlich txt?

Es ist doch sinnvoller ret als Pointer an den Callback zu übergeben und den dann zu nutzen. Dann entfällt auch die Copy-For-Schleife, die so sowieso ziemlich langsam ist.

Aber daran wirds wahrscheinlich nicht liegen. Ich kopier das mal ins C-Forum.
 
Zurück