<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Manuel,<br>
      thanks for submitting this issue.</p>
    <p>I think your hunch is probably correct - something inside the JDK
      is resetting the value of LastError.</p>
    <p>In Hotspot code I see some abstractions to preserve the LastError
      value (os_windows.cpp):</p>
    <pre style="background-color:#ffffff;color:#000000;font-family:'Source Code Pro',monospace;font-size:11.3pt;"><span style="color:#808080;font-style:italic;">// A number of wrappers for more frequently used system calls, to add standard logging.
</span><span style="color:#808080;font-style:italic;">
</span><span style="color:#000080;font-weight:bold;">struct </span>PreserveLastError {
  <span style="color:#000080;font-weight:bold;">const </span>DWORD v;
  PreserveLastError() : v(::GetLastError()) {}
  ~PreserveLastError() { ::SetLastError(v); }
};</pre>
    <p><br>
      And this is used in a number of OS-specific function calls, to
      avoid polluting the last error value.</p>
    <p>That said, when you are running with a debugger, especially
      inside an IDE (which might add its own hooks), I think most bets
      are off, as the debugger might indeed perform additional native
      calls which might not preserve lastError correctly.</p>
    <p>One experiment would be to try and debugging using jdb - so that
      at least we'd rule the IDE out, and see if the issue is still
      there. If that's the case we'll try to reach out to somebody more
      intimate with architetcure of JPDA, to see if that's something
      that can be addressed (perhaps in a way similar to what hotspot
      code seems to be already doing).</p>
    <p>Thanks<br>
      Maurizio<br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 12/08/2022 10:21, Manuel
      Bleichenbacher wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAA7F5jKAtsKpFAQ0Nn3swzWmzVaLu8mhYh-a3ny2PqOp8JJHRQ@mail.gmail.com">
      
      <div dir="ltr">Thanks for the work on project Panama. It's an
        exciting technology. I'm using it to make native operating
        system services available to Java.
        <div><br>
        </div>
        <div>On Windows I've run into an issue. This C/C++ Windows code:
          <div>
            <div><br>
            </div>
            <div>    BOOL res = WriteFile(INVALID_HANDLE_VALUE, NULL, 0,
              NULL, NULL);<br>
                  DWORD err = GetLastError();<br>
            </div>
          </div>
          <div>    printf("WriteFile result: %d, GetLastError result:
            %d\n", res, err);<br>
          </div>
          <div><br>
          </div>
          <div>prints (as expected):</div>
          <div><br>
          </div>
          <div>    WriteFile result: 0, GetLastError result: 6<br>
          </div>
          <div><br>
          </div>
          <div>6 is the value of the constant ERROR_INVALID_HANDLE.</div>
          <div><br>
          </div>
          <div>Using panama, I've translated the code to Java. The
            result is:</div>
          <div><br>
          </div>
          <div>Without debugger, the output is the same. Everything is
            ok.</div>
          <div><br>
          </div>
          <div>With the debugger, the result is incorrect:</div>
          <div><br>
          </div>
          <div>
            <div>    WriteFile result: 0, GetLastError result: 0<br>
            </div>
            <div><br>
            </div>
            <div>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?</div>
            <div><br>
            </div>
            <div>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.</div>
            <div><br>
            </div>
            <div>Is there something I'm not doing incorrectly? Or is
              there a fix or workaround?</div>
            <div><br>
            </div>
            <div>Here's the Java code:</div>
            <div><br>
            </div>
            <div>
              <pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(204,120,50)">import </span>java.lang.foreign.*<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">import </span>java.lang.invoke.MethodHandle<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">
</span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.MemoryAddress.<span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.ValueLayout.<span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.ValueLayout.<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">
</span><span style="color:rgb(204,120,50)">public class </span>WinApi {
    <span style="color:rgb(204,120,50)">static final </span>MethodHandle <span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func</span><span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">    static final </span>MethodHandle <span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func</span><span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">    static final </span>MemoryAddress <span style="color:rgb(152,118,170);font-style:italic">INVALID_HANDLE_VALUE </span>= MemoryAddress.<span style="font-style:italic">ofLong</span>(-<span style="color:rgb(104,151,187)">1</span>)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">
</span><span style="color:rgb(204,120,50)">    static </span>{
        <span style="color:rgb(204,120,50)">var </span>linker = Linker.<span style="font-style:italic">nativeLinker</span>()<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        var </span>lookup = SymbolLookup.<span style="font-style:italic">libraryLookup</span>(<span style="color:rgb(106,135,89)">"Kernel32"</span><span style="color:rgb(204,120,50)">, </span>MemorySession.<span style="font-style:italic">global</span>())<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">
</span><span style="color:rgb(204,120,50)">        </span><span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func </span>= linker.downcallHandle(
                lookup.lookup(<span style="color:rgb(106,135,89)">"WriteFile"</span>).get()<span style="color:rgb(204,120,50)">,
</span><span style="color:rgb(204,120,50)">                </span>FunctionDescriptor.<span style="font-style:italic">of</span>(<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span>)
        )<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span><span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func </span>= linker.downcallHandle(
                lookup.lookup(<span style="color:rgb(106,135,89)">"GetLastError"</span>).get()<span style="color:rgb(204,120,50)">,
</span><span style="color:rgb(204,120,50)">                </span>FunctionDescriptor.<span style="font-style:italic">of</span>(<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span>)
        )<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">    </span>}

    <span style="color:rgb(204,120,50)">public static void </span><span style="color:rgb(255,198,109)">main</span>(String[] args) {
        <span style="color:rgb(204,120,50)">var </span>res = <span style="font-style:italic">WriteFile</span>(<span style="color:rgb(152,118,170);font-style:italic">INVALID_HANDLE_VALUE</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span>)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        var </span>err = <span style="font-style:italic">GetLastError</span>()<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span>System.<span style="color:rgb(152,118,170);font-style:italic">out</span>.printf(<span style="color:rgb(106,135,89)">"WriteFile result: %d, GetLastError result: %d</span><span style="color:rgb(204,120,50)">\n</span><span style="color:rgb(106,135,89)">"</span><span style="color:rgb(204,120,50)">, </span>res<span style="color:rgb(204,120,50)">, </span>err)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">    </span>}

    <span style="color:rgb(204,120,50)">static int </span><span style="color:rgb(255,198,109)">WriteFile</span>(MemoryAddress hFile<span style="color:rgb(204,120,50)">, </span>MemoryAddress lpBuffer<span style="color:rgb(204,120,50)">, int </span>nNumberOfBytesToWrite<span style="color:rgb(204,120,50)">,
</span><span style="color:rgb(204,120,50)">                         </span>MemoryAddress lpNumberOfBytesWritten<span style="color:rgb(204,120,50)">, </span>MemoryAddress lpOverlapped) {
        <span style="color:rgb(204,120,50)">try </span>{
            <span style="color:rgb(204,120,50)">return </span>(<span style="color:rgb(204,120,50)">int</span>) <span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func</span>.invokeExact((Addressable)hFile<span style="color:rgb(204,120,50)">, </span>(Addressable)lpBuffer<span style="color:rgb(204,120,50)">, </span>nNumberOfBytesToWrite<span style="color:rgb(204,120,50)">,
</span><span style="color:rgb(204,120,50)">                    </span>(Addressable)lpNumberOfBytesWritten<span style="color:rgb(204,120,50)">, </span>(Addressable)lpOverlapped)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span>} <span style="color:rgb(204,120,50)">catch </span>(Throwable e) {
            <span style="color:rgb(204,120,50)">throw new </span>RuntimeException(e)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span>}
    }

    <span style="color:rgb(204,120,50)">static int </span><span style="color:rgb(255,198,109)">GetLastError</span>() {
        <span style="color:rgb(204,120,50)">try </span>{
            <span style="color:rgb(204,120,50)">return </span>(<span style="color:rgb(204,120,50)">int</span>) <span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func</span>.invokeExact()<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span>} <span style="color:rgb(204,120,50)">catch </span>(Throwable e) {
            <span style="color:rgb(204,120,50)">throw new </span>RuntimeException(e)<span style="color:rgb(204,120,50)">;
</span><span style="color:rgb(204,120,50)">        </span>}
    }
}</pre>
            </div>
            <div><br>
            </div>
          </div>
          <div>Cheers</div>
          <div>Manuel</div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>