2012-03-29 7 views
1

Ich brauchte eine Java-Anwendung, um die Windows-Registrierung zu manipulieren. Um dies zu tun, schrieb ich etwas nativen C++ Code und benutzte JNI um es aufzurufen.JNI Absturz außerhalb JVM - EXCEPTION_ACCESS_VIOLATION

Zum größten Teil funktioniert es. Während des Tests hatte ich noch nie von einem Problem gehört. In letzter Zeit hat jedoch ein Benutzer einen Absturz im C++ - Code festgestellt, der die JVM zum Absturz gebracht hat. Die Details sind unten. Ich habe fast keine C++ Erfahrung, also denke ich, dass ich dort die Hilfe brauche. Ich denke, das Problem hängt mit den Berechtigungen zusammen, denn wenn die Java-App als Administrator ausgeführt wird, verschwindet das Problem. Das Problem besteht darin, dass nicht alle Benutzer Administratorrechte auf ihren Computern haben.

hs_err_pid Log-Info:

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000076859083, pid=5316, tid=3116 
# 
# JRE version: 6.0_20-b02 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode windows-amd64) 
# Problematic frame: 
# C [kernel32.dll+0x9083] 
# 
# If you would like to submit a bug report, please visit: 
# http://java.sun.com/webapps/bugreport/crash.jsp 
# The crash happened outside the Java Virtual Machine in native code. 
# See problematic frame for where to report the bug. 
# 

Stack: [0x0000000013010000,0x0000000013110000], sp=0x000000001310f2d0, free space=3fc0000000000000000k 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
C [kernel32.dll+0x9083] 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
j my.package.WinRegUtils.SetKeyValue(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z+0 
j java.lang.Thread.run()V+11 
v ~StubRoutines::call_stub 

ist die native Code/Methode in Frage

JNIEXPORT jboolean JNICALL Java_my_package_WinRegUtils_SetKeyValue 
    (JNIEnv* env, jclass clazz, jstring jRootKey, jstring jKey, jstring jValueName, jstring jValueData, jstring jDataType) 
{ 
    bool success = false; 

    WCHAR* key_w; 
    WCHAR* valueName_w; 
    WCHAR* valueData_w; 
    WCHAR* dataType_w; 
    HKEY hKey; 

    const char* rootKey = env->GetStringUTFChars(jRootKey, false); 
    const char* key = env->GetStringUTFChars(jKey, false); 
    convertString(key, &key_w); 
    const char* valueName = env->GetStringUTFChars(jValueName, false); 
    convertString(valueName, &valueName_w); 
    const char* valueData = env->GetStringUTFChars(jValueData, false); 
    convertString(valueData, &valueData_w); 
    const char* dataType = env->GetStringUTFChars(jDataType, false); 
    convertString(dataType, &dataType_w); 

    HKEY root = GetRootHKEY(rootKey); 
    if (RegOpenKeyEx(root, key_w, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) 
    { 
     DWORD dwType; 
     BYTE* data; 
     DWORD length; 
     if (strcmp("REG_SZ", dataType) == 0) 
     { 
      dwType = REG_SZ; 
      data = (BYTE*)valueData_w; 
      length = wcslen(valueData_w) * sizeof(DWORD); 
     } 
     else if (strcmp("REG_DWORD", dataType) == 0) 
     { 
      dwType = REG_DWORD; 
      const DWORD intData = atoi(valueData); 
      data = (BYTE*)&intData; 
      length = sizeof(DWORD); 
     } 

     if (RegSetValueEx(hKey, valueName_w, 0, dwType, data, length) == ERROR_SUCCESS) 
     { 
      success = true; 
      RegCloseKey(hKey); 
     } 
    } 

    env->ReleaseStringUTFChars(jRootKey, rootKey); 
    env->ReleaseStringUTFChars(jKey, key); 
    env->ReleaseStringUTFChars(jValueName, valueName); 
    env->ReleaseStringUTFChars(jValueData, valueData); 
    env->ReleaseStringUTFChars(jDataType, dataType); 
    delete[] key_w, valueName_w, valueData_w, dataType_w; 

    return success; 
} 

Antwort

0

Debug, ein paar hinzufügen

printf("debug xxx"); 
fflush(stdout); 

in

Java_my_package_WinRegUtils_SetKeyValue() 

, um die fehlerhafte Leitung zu isolieren.

Verwandte Themen