JNI modify a static field of java

2

I am trying to modify a static field of java, but I got a strange problem. The Java project will throw exception if I don't put some redundancy code in C.

I am using the C code to produce the .dll

this is my Java code

public class Main {

    public static void main(String[] args) {
        Main instance = new Main();
        System.out.println("before change static field:" + staticString);
        instance.CModifyStaticField();
        System.out.println("after change static field:" + staticString);

    }
    private static String staticString = "static";

    private native  String letCModifyStaticField();

    private void CModifyStaticField() {
        letCModifyStaticField();
    }
    static {
        System.loadLibrary("JNI");
    }
}

and this is my C code

JNIEXPORT jstring JNICALL Java_Main_letCChangeStaticField
(JNIEnv *env, jobject jobj){
    jclass jclz = (*env)->GetObjectClass(env, jobj);

    //this is the point
    printf("jclz != NULL\n");

    jfieldID jfieldId = (*env)->GetStaticFieldID(env, jclz, "staticString", "Ljava/lang/String;");
    jstring jstr = (*env)->GetStaticObjectField(env, jclz, jfieldId);
    char* sourceStr = (*env)->GetStringUTFChars(env, jstr, JNI_FALSE);
    char* newChar = "new ";
    strcat(newChar, sourceStr);
    jstring newStr = (*env)->NewStringUTF(env, newChar);
    (*env)->SetStaticObjectField(env, jclz, jfieldId, newStr);
    return  newStr;
}

if I remove the printf() and run Java project,it throws a exception like this:

Current thread (0x0000000002a32800):  JavaThread "main" [_thread_in_vm, id=4212, stack(0x0000000002460000,0x0000000002560000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000000

Registers:
RAX=0x0000000000000000, RBX=0x0000000002a32800, RCX=0x0000000002a32800, RDX=0x00000007806fe1d8
RSP=0x000000000255f100, RBP=0x000000000255f228, RSI=0x0000000000000000, RDI=0x0000000000000000
R8 =0x0000000000000000, R9 =0x0000000075ad0000, R10=0x0000000000000000, R11=0x000000000255f130
R12=0x0000000000000000, R13=0x0000000019673188, R14=0x000000000255f248, R15=0x0000000002a32800
RIP=0x00000000753755c2, EFLAGS=0x0000000000010202

Top of Stack: (sp=0x000000000255f100)
0x000000000255f100:   000000000255f248 000000007536f2a7
0x000000000255f110:   0000000002a32800 0000000000000000
0x000000000255f120:   000000000255f228 000000000255f248
0x000000000255f130:   0000000002a32800 000000000245ede0
0x000000000255f140:   0000000000000b8b 0000000075838ec0
0x000000000255f150:   000000000255f1b0 00007ffbc4211378
0x000000000255f160:   0000000019673188 000000000255f228
0x000000000255f170:   0000000000000002 cccccccccccccccc
0x000000000255f180:   0000000019bd7e20 0000000000000000
0x000000000255f190:   cccccccccccccccc cccccccccccccccc
0x000000000255f1a0:   cccccccccccccccc cccccccccccccccc
0x000000000255f1b0:   0000000002b3835d 0000000002b48c67
0x000000000255f1c0:   0000000002a329f8 000000000255f248
0x000000000255f1d0:   0000000000000002 0000000002a32800
0x000000000255f1e0:   0000000002b48962 000000000255f1e8
0x000000000255f1f0:   0000000019673188 000000000255f248 

Instructions: (pc=0x00000000753755c2)
0x00000000753755a2:   8b 0e 45 33 c0 33 d2 48 8b cb c6 44 24 28 01 48
0x00000000753755b2:   89 74 24 20 e8 e5 75 07 00 40 38 3d 7e bf 6c 00
0x00000000753755c2:   48 8b 06 48 63 4e 10 48 8b 50 68 74 1b 8b 0c 11
0x00000000753755d2:   85 c9 74 18 8b f9 8b 0d ba f1 65 00 48 d3 e7 48 


Register to memory mapping:

RAX=0x0000000000000000 is an unknown value
RBX=0x0000000002a32800 is a thread
RCX=0x0000000002a32800 is a thread
RDX=0x00000007806fe1d8 is an oop
java.lang.NoSuchFieldError 
 - klass: 'java/lang/NoSuchFieldError'
RSP=0x000000000255f100 is pointing into the stack for thread: 0x0000000002a32800
RBP=0x000000000255f228 is pointing into the stack for thread: 0x0000000002a32800
RSI=0x0000000000000000 is an unknown value
RDI=0x0000000000000000 is an unknown value
R8 =0x0000000000000000 is an unknown value
R9 =0x0000000075ad0000 is an unknown value
R10=0x0000000000000000 is an unknown value
R11=0x000000000255f130 is pointing into the stack for thread: 0x0000000002a32800
R12=0x0000000000000000 is an unknown value
R13={method} {0x0000000019673190} 'letCChangeStaticField' '()Ljava/lang/String;' in 'Main'
R14=0x000000000255f248 is pointing into the stack for thread: 0x0000000002a32800
R15=0x0000000002a32800 is a thread


Stack: [0x0000000002460000,0x0000000002560000],  sp=0x000000000255f100,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0x1455c2]
C  [JNI.dll+0x1378]  Java_Main_letCChangeStaticField+0x88
C  0x0000000002b48c67

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  Main.letCChangeStaticField()Ljava/lang/String;+0
j  Main.CAllocStaticField()V+1
j  Main.main([Ljava/lang/String;)V+123
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x000000001b0b2800 JavaThread "Service Thread" daemon [_thread_blocked, id=12496, stack(0x000000001b9d0000,0x000000001bad0000)]
  0x000000001b029000 JavaThread "C1 CompilerThread2" daemon [_thread_blocked, id=11392, stack(0x000000001b8d0000,0x000000001b9d0000)]
  0x000000001b028000 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=11784, stack(0x000000001b7d0000,0x000000001b8d0000)]
  0x000000001b017000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=12172, stack(0x000000001b6d0000,0x000000001b7d0000)]
  0x000000001b014800 JavaThread "Monitor Ctrl-Break" daemon [_thread_in_native, id=9204, stack(0x000000001b5d0000,0x000000001b6d0000)]
  0x0000000019c6b800 JavaThread "Attach Listener" daemon [_thread_blocked, id=7176, stack(0x000000001b4d0000,0x000000001b5d0000)]
  0x000000001afd8800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=13860, stack(0x000000001b3d0000,0x000000001b4d0000)]
  0x0000000019bf8800 JavaThread "Finalizer" daemon [_thread_blocked, id=14108, stack(0x000000001ae70000,0x000000001af70000)]
  0x0000000002b24000 JavaThread "Reference Handler" daemon [_thread_blocked, id=1092, stack(0x000000001ad70000,0x000000001ae70000)]
=>0x0000000002a32800 JavaThread "main" [_thread_in_vm, id=4212, stack(0x0000000002460000,0x0000000002560000)]

Other Threads:
  0x0000000019bd7800 VMThread [stack: 0x000000001ac70000,0x000000001ad70000] [id=14300]
  0x000000001b0d3800 WatcherThread [stack: 0x000000001bad0000,0x000000001bbd0000] [id=6412]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap:
 PSYoungGen      total 57344K, used 3940K [0x0000000780580000, 0x0000000784580000, 0x00000007c0000000)
  eden space 49152K, 8% used [0x0000000780580000,0x00000007809590f0,0x0000000783580000)
  from space 8192K, 0% used [0x0000000783d80000,0x0000000783d80000,0x0000000784580000)
  to   space 8192K, 0% used [0x0000000783580000,0x0000000783580000,0x0000000783d80000)
 ParOldGen       total 131072K, used 0K [0x0000000701000000, 0x0000000709000000, 0x0000000780580000)
  object space 131072K, 0% used [0x0000000701000000,0x0000000701000000,0x0000000709000000)
 Metaspace       used 3445K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 376K, capacity 388K, committed 512K, reserved 1048576K

Card table byte_map: [0x0000000011ef0000,0x00000000124f0000] byte_map_base: 0x000000000e6e8000

Marking Bits: (ParMarkBitMap*) 0x0000000075a508c0
 Begin Bits: [0x0000000012cf0000, 0x0000000015cb0000)
 End Bits:   [0x0000000015cb0000, 0x0000000018c70000)

Polling page: 0x0000000000770000

CodeCache: size=245760Kb used=1118Kb max_used=1118Kb free=244641Kb
 bounds [0x0000000002b30000, 0x0000000002da0000, 0x0000000011b30000]
 total_blobs=283 nmethods=25 adapters=171
 compilation: enabled

Compilation events (10 events):
Event: 0.174 Thread 0x000000001b029000   20       3       java.util.HashMap::hash (20 bytes)
Event: 0.174 Thread 0x000000001b029000 nmethod 20 0x0000000002c44990 code [0x0000000002c44b00, 0x0000000002c44d48]
Event: 0.174 Thread 0x000000001b029000   21       3       java.lang.String::indexOf (7 bytes)
Event: 0.175 Thread 0x000000001b029000 nmethod 21 0x0000000002c45410 code [0x0000000002c45580, 0x0000000002c45788]
Event: 0.175 Thread 0x000000001b029000   22       3       java.lang.String::indexOf (70 bytes)
Event: 0.175 Thread 0x000000001b029000 nmethod 22 0x0000000002c45810 code [0x0000000002c459a0, 0x0000000002c45d48]
Event: 0.175 Thread 0x000000001b029000   23       3       java.util.HashMap::getNode (148 bytes)
Event: 0.176 Thread 0x000000001b029000 nmethod 23 0x0000000002c45e90 code [0x0000000002c46060, 0x0000000002c46a08]
Event: 0.181 Thread 0x000000001b029000   24       3       java.util.concurrent.ConcurrentHashMap::tabAt (21 bytes)
Event: 0.181 Thread 0x000000001b029000 nmethod 24 0x0000000002c47810 code [0x0000000002c47960, 0x0000000002c47b90]

GC Heap History (0 events):
No events

Deoptimization events (0 events):
No events

Classes redefined (0 events):
No events

Internal exceptions (3 events):
Event: 0.048 Thread 0x0000000002a32800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; name or signature does not match> (0x0000000780587cb0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u171\10807\hotspot
Event: 0.048 Thread 0x0000000002a32800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x0000000780587f98) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u171\10807\hotspot\src\share\vm\prim
Event: 0.181 Thread 0x0000000002a32800 Exception <a 'java/lang/NoSuchFieldError': staticString> (0x00000007806fe1d8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u171\10807\hotspot\src\share\vm\prims\jni.cpp, line 2955]

Events (10 events):
Event: 0.177 loading class sun/net/NetHooks
Event: 0.177 loading class sun/net/NetHooks done
Event: 0.178 loading class java/net/Socket$2
Event: 0.178 loading class java/net/Socket$2 done
Event: 0.178 loading class java/net/SocketInputStream
Event: 0.178 loading class java/net/SocketInputStream done
Event: 0.178 loading class sun/nio/cs/US_ASCII$Decoder
Event: 0.179 loading class sun/nio/cs/US_ASCII$Decoder done
Event: 0.181 loading class java/lang/NoSuchFieldError
Event: 0.181 loading class java/lang/NoSuchFieldError done


Dynamic libraries:
0x00007ff7defc0000 - 0x00007ff7deff7000     D:\MyEclipse\JDK\bin\java.exe
0x00007ffbda340000 - 0x00007ffbda521000     C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffbd9f80000 - 0x00007ffbda031000     C:\WINDOWS\System32\KERNEL32.DLL
0x00007ffbd6990000 - 0x00007ffbd6c03000     C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffbd8160000 - 0x00007ffbd8201000     C:\WINDOWS\System32\ADVAPI32.dll
0x00007ffbda260000 - 0x00007ffbda2fe000     C:\WINDOWS\System32\msvcrt.dll
0x00007ffbda070000 - 0x00007ffbda0cb000     C:\WINDOWS\System32\sechost.dll
0x00007ffbd77c0000 - 0x00007ffbd78e4000     C:\WINDOWS\System32\RPCRT4.dll
0x00007ffbda0d0000 - 0x00007ffbda260000     C:\WINDOWS\System32\USER32.dll
0x00007ffbd6700000 - 0x00007ffbd6720000     C:\WINDOWS\System32\win32u.dll
0x00007ffbd79c0000 - 0x00007ffbd79e8000     C:\WINDOWS\System32\GDI32.dll
0x00007ffbd7420000 - 0x00007ffbd75b1000     C:\WINDOWS\System32\gdi32full.dll
0x00007ffbd7620000 - 0x00007ffbd76bf000     C:\WINDOWS\System32\msvcp_win.dll
0x00007ffbd76c0000 - 0x00007ffbd77b8000     C:\WINDOWS\System32\ucrtbase.dll
0x00007ffbc90a0000 - 0x00007ffbc9309000     C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.17134.982_none_fb3fa44f30680781\COMCTL32.dll
0x00007ffbd7ae0000 - 0x00007ffbd7e02000     C:\WINDOWS\System32\combase.dll
0x00007ffbd6720000 - 0x00007ffbd6799000     C:\WINDOWS\System32\bcryptPrimitives.dll
0x00007ffbd8010000 - 0x00007ffbd803d000     C:\WINDOWS\System32\IMM32.DLL
0x0000000075ad0000 - 0x0000000075ba2000     D:\MyEclipse\JDK\jre\bin\msvcr100.dll
0x0000000075230000 - 0x0000000075ad0000     D:\MyEclipse\JDK\jre\bin\server\jvm.dll
0x00007ffbda060000 - 0x00007ffbda068000     C:\WINDOWS\System32\PSAPI.DLL
0x00007ffbd4630000 - 0x00007ffbd4653000     C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007ffbd22f0000 - 0x00007ffbd22fa000     C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007ffbd4600000 - 0x00007ffbd462a000     C:\WINDOWS\SYSTEM32\winmmbase.dll
0x00007ffbd6c10000 - 0x00007ffbd6c59000     C:\WINDOWS\System32\cfgmgr32.dll
0x00007ffbcf220000 - 0x00007ffbcf229000     C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007ffbd80f0000 - 0x00007ffbd815c000     C:\WINDOWS\System32\WS2_32.dll
0x0000000075220000 - 0x000000007522f000     D:\MyEclipse\JDK\jre\bin\verify.dll
0x00000000751f0000 - 0x0000000075219000     D:\MyEclipse\JDK\jre\bin\java.dll
0x00000000751a0000 - 0x00000000751c3000     D:\MyEclipse\JDK\jre\bin\instrument.dll
0x00000000751d0000 - 0x00000000751e6000     D:\MyEclipse\JDK\jre\bin\zip.dll
0x00007ffbd8a90000 - 0x00007ffbd9ed2000     C:\WINDOWS\System32\SHELL32.dll
0x00007ffbd8040000 - 0x00007ffbd80e9000     C:\WINDOWS\System32\shcore.dll
0x00007ffbd6c60000 - 0x00007ffbd736e000     C:\WINDOWS\System32\windows.storage.dll
0x00007ffbd7960000 - 0x00007ffbd79b1000     C:\WINDOWS\System32\shlwapi.dll
0x00007ffbd66e0000 - 0x00007ffbd66f1000     C:\WINDOWS\System32\kernel.appcore.dll
0x00007ffbd66c0000 - 0x00007ffbd66df000     C:\WINDOWS\System32\profapi.dll
0x00007ffbd6640000 - 0x00007ffbd668c000     C:\WINDOWS\System32\powrprof.dll
0x00007ffbd6690000 - 0x00007ffbd669a000     C:\WINDOWS\System32\FLTLIB.DLL
0x00007ffbc54f0000 - 0x00007ffbc550a000     D:\IntelliJ IDEA 2018.2.6\bin\breakgen64.dll
0x0000000075180000 - 0x000000007519a000     D:\MyEclipse\JDK\jre\bin\net.dll
0x00007ffbd5e40000 - 0x00007ffbd5ea6000     C:\WINDOWS\system32\mswsock.dll
0x00007ffbc4210000 - 0x00007ffbc421f000     D:\C_WorkSpace\JNI_C\JNI\x64\Debug\JNI.dll
0x00007ffb8cd00000 - 0x00007ffb8cf11000     C:\WINDOWS\SYSTEM32\MSVCR120D.dll
0x00007ffbc47e0000 - 0x00007ffbc49a9000     C:\WINDOWS\SYSTEM32\dbghelp.dll

VM Arguments:
jvm_args: -Djava.library.path=D:\C_WorkSpace\JNI_C\JNI\x64\Debug -javaagent:D:\IntelliJ IDEA 2018.2.6\lib\idea_rt.jar=14418:D:\IntelliJ IDEA 2018.2.6\bin -Dfile.encoding=UTF-8 
java_command: Main
java_class_path (initial): D:\MyEclipse\JDK\jre\lib\charsets.jar;D:\MyEclipse\JDK\jre\lib\deploy.jar;D:\MyEclipse\JDK\jre\lib\ext\access-bridge-64.jar;D:\MyEclipse\JDK\jre\lib\ext\cldrdata.jar;D:\MyEclipse\JDK\jre\lib\ext\dnsns.jar;D:\MyEclipse\JDK\jre\lib\ext\jaccess.jar;D:\MyEclipse\JDK\jre\lib\ext\jfxrt.jar;D:\MyEclipse\JDK\jre\lib\ext\localedata.jar;D:\MyEclipse\JDK\jre\lib\ext\nashorn.jar;D:\MyEclipse\JDK\jre\lib\ext\sunec.jar;D:\MyEclipse\JDK\jre\lib\ext\sunjce_provider.jar;D:\MyEclipse\JDK\jre\lib\ext\sunmscapi.jar;D:\MyEclipse\JDK\jre\lib\ext\sunpkcs11.jar;D:\MyEclipse\JDK\jre\lib\ext\zipfs.jar;D:\MyEclipse\JDK\jre\lib\javaws.jar;D:\MyEclipse\JDK\jre\lib\jce.jar;D:\MyEclipse\JDK\jre\lib\jfr.jar;D:\MyEclipse\JDK\jre\lib\jfxswt.jar;D:\MyEclipse\JDK\jre\lib\jsse.jar;D:\MyEclipse\JDK\jre\lib\management-agent.jar;D:\MyEclipse\JDK\jre\lib\plugin.jar;D:\MyEclipse\JDK\jre\lib\resources.jar;D:\MyEclipse\JDK\jre\lib\rt.jar;D:\C_WorkSpace\JNI\out\production\JNI;D:\IntelliJ IDEA 2018.2.6\lib\idea_rt.jar
Launcher Type: SUN_STANDARD

Environment Variables:
JAVA_HOME=D:\MyEclipse\JDK
PATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;D:\MyEclipse\JDK\bin;D:\MyEclipse\Mysql\MySQL Server5.5\bin;D:\MyEclipse\Mysql Server 5.5\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Android\SDK\ndk-bundle;D:\Git\cmd;D:\Git\bin;D:\flutter\bin;D:\Android\SDK\platform-tools;D:\Android\SDK\tools;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;D:\Fiddler\Fiddler2;D:\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Local\GitHubDesktop\bin
USERNAME=Administrator
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 60 Stepping 3, GenuineIntel

but if I holds the redundant print code,or change it to other redundant code,the project runs correctly.I don't know what I'm doing wrong.

java
c
java-native-interface
asked on Stack Overflow Aug 30, 2019 by Kepler • edited Aug 30, 2019 by Ram Pratap Ranjan

1 Answer

5

This is wrong:

char* newChar = "new ";
strcat(newChar, sourceStr);

That code attempts to modify a string literal and is undefined behavior:

If the program attempts to modify such an array, the behavior is undefined.

You're also completely failing to check any of the returns you get from your JNI calls for errors or exceptions. You just assume the class you get is a valid value. You just assume the field ID is a valid value, you just assume there are no exceptions for any of your calls. You can not write robust JNI code without checking for errors and exceptions after every call.

answered on Stack Overflow Aug 30, 2019 by Andrew Henle

User contributions licensed under CC BY-SA 3.0