GetLastError() (with and without debugger)

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Aug 12 14:55:13 UTC 2022


On 12/08/2022 15:53, Radosław Smogura wrote:
>
> Hi all,
>
> I could guess that debugger uses network and uses low level API to 
> send and receive packets, which can cause error to be reset. But this 
> is only my guess.
>
I tend to agree with your (educated) guess.

Maurizio

> Kind regards,
>
> Rado Smogura
>
> *From: *Maurizio Cimadamore <mailto:maurizio.cimadamore at oracle.com>
> *Sent: *Friday, August 12, 2022 4:51 PM
> *To: *Pedro Lamarão <mailto:pedro.lamarao at prodist.com.br>; Manuel 
> Bleichenbacher <mailto:manuel.bleichenbacher at gmail.com>
> *Cc: *panama-dev at openjdk.org
> *Subject: *Re: GetLastError() (with and without debugger)
>
> On 12/08/2022 15:43, Pedro Lamarão wrote:
>
>         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.
>
> And JNI - I doubt there's anything Panama specific here (unless proven 
> otherwise).
>
> So that it's clear - it's not that GetLastError fails in general. It 
> fails when a debugger is attached. As I explained, this could be due 
> to _which_ debugger is attached, or some existing issue (predating 
> Panama) in the way jdb/JPDA deal with some Windows system calls.
>
> Maurizio
>
>     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
>     <https://urldefense.com/v3/__https://www.prodist.com.br__;!!ACWV5N9M2RV99hQ!KJSQL21z0JqqkoKWi_1XM7-gUTuT4M89VbpDuAwRrxMfDBoh5PVL6l-TkZVGAzxGZkk0wM2pgmZU3ewcNenvlw$>
>
>     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/3470b4f6/attachment-0001.htm>


More information about the panama-dev mailing list