GetLastError() (with and without debugger)

Pedro Lamarão pedro.lamarao at prodist.com.br
Fri Aug 12 14:43:24 UTC 2022


> This is incorrect. WriteFile() indicates an error, but GetLastError()
> returns 0 (= NO_ERROR). Could it be that the debugger calls another Windows
> API function between those two functions, resetting the last error?
>
> In my project that's a major issue. Since the software behaves incorrectly
> with the debugger, the software can no longer be debugged. This doesn't
> just affect it when debugging this particular piece of code but anytime
> this code is run in a debugging session.
>


This would be a blocker for all applications of Windows API functions via
panama.
Windows Sockets has a similar mechanism called WSAGetLastError.

As far as I know, GetLastError and WSAGetLastError are getter-like
functions for effectively thread local data.
It is safe to call Windows API functions from inside the same process but
another thread.
If some piece of software infrastructure has perturbed your program, then
it has called a Windows API function from inside our program



> Is there something I'm not doing incorrectly? Or is there a fix or
> workaround?
>
> Here's the Java code:
>
> import java.lang.foreign.*;
> import java.lang.invoke.MethodHandle;
>
> import static java.lang.foreign.MemoryAddress.NULL;
> import static java.lang.foreign.ValueLayout.ADDRESS;
> import static java.lang.foreign.ValueLayout.JAVA_INT;
>
> public class WinApi {
>     static final MethodHandle WriteFile$Func;
>     static final MethodHandle GetLastError$Func;
>     static final MemoryAddress INVALID_HANDLE_VALUE = MemoryAddress.ofLong(-1);
>
>     static {
>         var linker = Linker.nativeLinker();
>         var lookup = SymbolLookup.libraryLookup("Kernel32", MemorySession.global());
>
>         WriteFile$Func = linker.downcallHandle(
>                 lookup.lookup("WriteFile").get(),
>                 FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS, JAVA_INT, ADDRESS, ADDRESS)
>         );
>         GetLastError$Func = linker.downcallHandle(
>                 lookup.lookup("GetLastError").get(),
>                 FunctionDescriptor.of(JAVA_INT)
>         );
>     }
>
>     public static void main(String[] args) {
>         var res = WriteFile(INVALID_HANDLE_VALUE, NULL, 0, NULL, NULL);
>         var err = GetLastError();
>         System.out.printf("WriteFile result: %d, GetLastError result: %d\n", res, err);
>     }
>
>     static int WriteFile(MemoryAddress hFile, MemoryAddress lpBuffer, int nNumberOfBytesToWrite,
>                          MemoryAddress lpNumberOfBytesWritten, MemoryAddress lpOverlapped) {
>         try {
>             return (int) WriteFile$Func.invokeExact((Addressable)hFile, (Addressable)lpBuffer, nNumberOfBytesToWrite,
>                     (Addressable)lpNumberOfBytesWritten, (Addressable)lpOverlapped);
>         } catch (Throwable e) {
>             throw new RuntimeException(e);
>         }
>     }
>
>     static int GetLastError() {
>         try {
>             return (int) GetLastError$Func.invokeExact();
>         } catch (Throwable e) {
>             throw new RuntimeException(e);
>         }
>     }
> }
>
>
> Cheers
> Manuel
>
>
>

-- 
Pedro Lamarão
https://www.prodist.com.br
Securing Critical Systems
Tel: +55 11 4380-6585

Antes de imprimir esta mensagem e seus anexos, certifique-se que seja
realmente necessário.
Proteger o meio ambiente é nosso dever.
Before printing this e-mail or attachments, be sure it is necessary.
It is in our hands to protect the environment.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20220812/7fccc29e/attachment-0001.htm>


More information about the panama-dev mailing list