<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0in;
font-size:10.0pt;
font-family:"Courier New";}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Courier New";}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi all,</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Kind regards,</p>
<p class="MsoNormal">Rado Smogura</p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="border:none;padding:0in"><b>From: </b><a href="mailto:maurizio.cimadamore@oracle.com">Maurizio Cimadamore</a><br>
<b>Sent: </b>Friday, August 12, 2022 4:51 PM<br>
<b>To: </b><a href="mailto:pedro.lamarao@prodist.com.br">Pedro Lamarão</a>; <a href="mailto:manuel.bleichenbacher@gmail.com">
Manuel Bleichenbacher</a><br>
<b>Cc: </b><a href="mailto:panama-dev@openjdk.org">panama-dev@openjdk.org</a><br>
<b>Subject: </b>Re: GetLastError() (with and without debugger)</p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p><o:p> </o:p></p>
<div>
<p class="MsoNormal">On 12/08/2022 15:43, Pedro Lamarão wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">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?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">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.<o:p></o:p></p>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">This would be a blocker for all applications of Windows API functions via panama.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Windows Sockets has a similar mechanism called WSAGetLastError.<o:p></o:p></p>
</div>
</div>
</div>
</blockquote>
<p>And JNI - I doubt there's anything Panama specific here (unless proven otherwise).</p>
<p>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.</p>
<p>Maurizio</p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">As far as I know, GetLastError and WSAGetLastError are getter-like functions for effectively thread local data.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">It is safe to call Windows API functions from inside the same process but another thread.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">If some piece of software infrastructure has perturbed your program, then it has called a Windows API function from inside our program<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">Is there something I'm not doing incorrectly? Or is there a fix or workaround?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">Here's the Java code:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt"><o:p> </o:p></p>
</div>
<div>
<pre style="background:#2B2B2B"><span style="color:#CC7832">import </span><span style="color:#A9B7C6">java.lang.foreign.*</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832">import </span><span style="color:#A9B7C6">java.lang.invoke.MethodHandle</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832">import static </span><span style="color:#A9B7C6">java.lang.foreign.MemoryAddress.</span><i><span style="color:#9876AA">NULL</span></i><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832">import static </span><span style="color:#A9B7C6">java.lang.foreign.ValueLayout.</span><i><span style="color:#9876AA">ADDRESS</span></i><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832">import static </span><span style="color:#A9B7C6">java.lang.foreign.ValueLayout.</span><i><span style="color:#9876AA">JAVA_INT</span></i><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832">public class </span><span style="color:#A9B7C6">WinApi {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">static final </span><span style="color:#A9B7C6">MethodHandle </span><i><span style="color:#9876AA">WriteFile$Func</span></i><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> static final </span><span style="color:#A9B7C6">MethodHandle </span><i><span style="color:#9876AA">GetLastError$Func</span></i><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> static final </span><span style="color:#A9B7C6">MemoryAddress </span><i><span style="color:#9876AA">INVALID_HANDLE_VALUE </span></i><span style="color:#A9B7C6">= MemoryAddress.<i>ofLong</i>(-</span><span style="color:#6897BB">1</span><span style="color:#A9B7C6">)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> static </span><span style="color:#A9B7C6">{<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">var </span><span style="color:#A9B7C6">linker = Linker.<i>nativeLinker</i>()</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> var </span><span style="color:#A9B7C6">lookup = SymbolLookup.<i>libraryLookup</i>(</span><span style="color:#6A8759">"Kernel32"</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">MemorySession.<i>global</i>())</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><i><span style="color:#9876AA">WriteFile$Func </span></i><span style="color:#A9B7C6">= linker.downcallHandle(<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> lookup.lookup(</span><span style="color:#6A8759">"WriteFile"</span><span style="color:#A9B7C6">).get()</span><span style="color:#CC7832">,<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">FunctionDescriptor.<i>of</i>(</span><i><span style="color:#9876AA">JAVA_INT</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">ADDRESS</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">ADDRESS</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">JAVA_INT</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">ADDRESS</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">ADDRESS</span></i><span style="color:#A9B7C6">)<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> )</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><i><span style="color:#9876AA">GetLastError$Func </span></i><span style="color:#A9B7C6">= linker.downcallHandle(<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> lookup.lookup(</span><span style="color:#6A8759">"GetLastError"</span><span style="color:#A9B7C6">).get()</span><span style="color:#CC7832">,<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">FunctionDescriptor.<i>of</i>(</span><i><span style="color:#9876AA">JAVA_INT</span></i><span style="color:#A9B7C6">)<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> )</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">}<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">public static void </span><span style="color:#FFC66D">main</span><span style="color:#A9B7C6">(String[] args) {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">var </span><span style="color:#A9B7C6">res = <i>WriteFile</i>(</span><i><span style="color:#9876AA">INVALID_HANDLE_VALUE</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">NULL</span></i><span style="color:#CC7832">, </span><span style="color:#6897BB">0</span><span style="color:#CC7832">, </span><i><span style="color:#9876AA">NULL</span></i><span style="color:#CC7832">, </span><i><span style="color:#9876AA">NULL</span></i><span style="color:#A9B7C6">)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> var </span><span style="color:#A9B7C6">err = <i>GetLastError</i>()</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">System.</span><i><span style="color:#9876AA">out</span></i><span style="color:#A9B7C6">.printf(</span><span style="color:#6A8759">"WriteFile result: %d, GetLastError result: %d</span><span style="color:#CC7832">\n</span><span style="color:#6A8759">"</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">res</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">err)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">}<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">static int </span><span style="color:#FFC66D">WriteFile</span><span style="color:#A9B7C6">(MemoryAddress hFile</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">MemoryAddress lpBuffer</span><span style="color:#CC7832">, int </span><span style="color:#A9B7C6">nNumberOfBytesToWrite</span><span style="color:#CC7832">,<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">MemoryAddress lpNumberOfBytesWritten</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">MemoryAddress lpOverlapped) {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">try </span><span style="color:#A9B7C6">{<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">return </span><span style="color:#A9B7C6">(</span><span style="color:#CC7832">int</span><span style="color:#A9B7C6">) </span><i><span style="color:#9876AA">WriteFile$Func</span></i><span style="color:#A9B7C6">.invokeExact((Addressable)hFile</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">(Addressable)lpBuffer</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">nNumberOfBytesToWrite</span><span style="color:#CC7832">,<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">(Addressable)lpNumberOfBytesWritten</span><span style="color:#CC7832">, </span><span style="color:#A9B7C6">(Addressable)lpOverlapped)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">} </span><span style="color:#CC7832">catch </span><span style="color:#A9B7C6">(Throwable e) {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">throw new </span><span style="color:#A9B7C6">RuntimeException(e)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">}<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> }<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"><o:p> </o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">static int </span><span style="color:#FFC66D">GetLastError</span><span style="color:#A9B7C6">() {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">try </span><span style="color:#A9B7C6">{<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">return </span><span style="color:#A9B7C6">(</span><span style="color:#CC7832">int</span><span style="color:#A9B7C6">) </span><i><span style="color:#9876AA">GetLastError$Func</span></i><span style="color:#A9B7C6">.invokeExact()</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">} </span><span style="color:#CC7832">catch </span><span style="color:#A9B7C6">(Throwable e) {<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> </span><span style="color:#CC7832">throw new </span><span style="color:#A9B7C6">RuntimeException(e)</span><span style="color:#CC7832">;<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#CC7832"> </span><span style="color:#A9B7C6">}<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6"> }<o:p></o:p></span></pre>
<pre style="background:#2B2B2B"><span style="color:#A9B7C6">}<o:p></o:p></span></pre>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt"><o:p> </o:p></p>
</div>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">Cheers<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:40.8pt">Manuel<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:0in;margin-right:0in;margin-bottom:12.0pt;margin-left:40.8pt">
<o:p> </o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal">-- <o:p></o:p></p>
<div>
<div>
<div>
<p class="MsoNormal">Pedro Lamarão<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.prodist.com.br" target="_blank">https://www.prodist.com.br</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Securing Critical Systems<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Tel: +55 11 4380-6585<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><img border="0" width="300" height="59" style="width:3.125in;height:.618in" id="_x0000_i1025" src="https://ci3.googleusercontent.com/mail-sig/AIorK4wgjsxiTyEHhb40ITzhw-mChttfn1y6GautnhGEr5tVa82AzYOrJJ9lEh-34sfDfoCQkFlQ7oY"><o:p></o:p></p>
</div>
</div>
</div>
</div>
</blockquote>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-right:.5in;margin-bottom:12.0pt;margin-left:.5in">
<span style="font-size:8.0pt;font-family:"Arial",sans-serif;color:#003366">Antes de imprimir esta mensagem e seus anexos, certifique-se que seja realmente necessário.<br>
Proteger o meio ambiente é nosso dever.<br>
Before printing this e-mail or attachments, be sure it is necessary.<br>
It is in our hands to protect the environment.</span><span style="color:#222222"><o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>