JDK 20 |
---|
20 b15Fixed |
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
It seems that when running a program in a debugger (e.g. jdb), the value of GetLastError can be overwritten, and the behavior of the program essentially changes. Take for instance this example program: ``` import java.lang.invoke.MethodHandle; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; public class Main { public static void main(String[] args) throws Throwable { Linker linker = Linker.nativeLinker(); System.loadLibrary("Kernel32"); SymbolLookup lookup = SymbolLookup.loaderLookup(); MethodHandle getLastError = linker.downcallHandle( lookup.lookup("GetLastError").orElseThrow(), FunctionDescriptor.of(JAVA_INT)); MethodHandle setLastError = linker.downcallHandle( lookup.lookup("SetLastError").orElseThrow(), FunctionDescriptor.ofVoid(JAVA_INT)); setLastError.invoke(42); System.out.println(getLastError.invoke()); } } ``` (Note that the same issue occurs with JNI, but the reproducer is more complex since it requires a native library to be compiled as well). Compile with: `javac --release 20 --enable-preview -d classes Main.java`. Then, when running normally with: `java --enable-preview -cp classes Main` the program prints '42'. However, when the same program is run in `jdb` with `jdb -R--enable-preview -classpath classes Main`, the program prints '0'. The GetLastError value is thread local, so it seems that some debugging routine is overwriting the value by calling Windows API methods on the debuggee thread, and afterwards doesn't restore the previous error value.
|