-
Bug
-
Resolution: Fixed
-
P3
-
17, 20
-
b15
-
generic
-
windows
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.
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.
- relates to
-
JDK-8293813 ProblemList com/sun/jdi/JdbLastErrorTest.java on windows-x64 in Xcomp mode
-
- Resolved
-
-
JDK-8289091 move oop safety check from SharedRuntime::get_java_tid() to JavaThread::threadObj()
-
- Resolved
-
-
JDK-8296913 Correct enable preview idiom in JdbLastErrorTest.java
-
- Resolved
-
-
JDK-8293829 Windows native last error value cleared with -Xcomp or -Xint (but not neither)
-
- Closed
-
-
JDK-8305913 com/sun/jdi/JdbLastErrorTest.java failed with "'lastError = 42' missing from stdout/stderr"
-
- Closed
-
(2 links to)