<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Actually it might be possible to view t.interrupted as true, but
      it would need to be done so from another thread. I think you can
      have Thread A sitting in a loop that doesn't do anything
      interruptible. Then in Thread B you can interrupt Thread A and
      then have Thread B hit a SUSPEND_ALL breakpoint. At that point if
      you viewed Thread A in the debugger, the interrupted field should
      be set true.</p>
    <p><br>
    </p>
    <p>Chris</p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 8/21/24 12:59 PM, Chris Plummer
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:e506a682-b1c2-4a08-a4ff-9e9ea0b7d422@oracle.com">
      
      <p>In your video you are stepping through the following:</p>
      <p><br>
      </p>
      <p>    public static boolean interrupted() {<br>
                Thread t = currentThread();<br>
                boolean interrupted = t.interrupted;<br>
                // We may have been interrupted the moment after we read
        the field,<br>
                // so only clear the field if we saw that it was set and
        will return<br>
                // true; otherwise we could lose an interrupt.<br>
                if (interrupted) {<br>
                    t.interrupted = false;<br>
                    clearInterruptEvent();<br>
                }<br>
                return interrupted;<br>
            }<br>
      </p>
      <p><br>
      </p>
      <p>The debugger is showing t.interrupted as false, but when you
        step over the assignment to the interrupted local variable, it
        ends up assigning true and interrupted() returns true as a
        result. Yes, this seems very odd, but there is an explanation.</p>
      <p><br>
      </p>
      <p>When you hit the breakpoint, there is an interrupt pending. As
        I mentioned earlier, the first RawMonitorWait that the debugger
        does on this thread will end up being interrupted as a result.
        The debug agent marks the thread as having been interrupted, and
        then does the wait again. So at this point t.interrupted will be
        false but ThreadNode->pendingInterrupt will be true. When the
        debug agent (and the debugger) are all done handling the event
        and the thread is resumed, the debug agent ends up in
        threadControl_onEventHandlerExit(), which checks the
        ThreadNode->pendingInterrupt flag and will reraise the
        interrupt if true. This means while the debugger is stopped at
        the event, the Thread's interrupted field is false, but once the
        Thread is resumed, it gets set true as a resulting of reraising
        the pending interrupt.</p>
      <p><br>
      </p>
      <p>I think given how things work with the debug agent and
        interrupts, the debugger may never be able to observe
        t.interrupt set to true. Note that in your video walkthrough,
        even though it seems odd (and wrong) that t.interrupted is set
        false, the stepping you did worked properly. The thread is
        indeed marked as interrupted as it should be, and the
        interrupted() method returned true as it should. The only thing
        that is "wrong" is the misleading display of the t.interrupted
        field as false. Possibly this could be fixed by having the debug
        agent special case the access of that field and consult with
        ThreadNode->pendingInterrupt, but to me it doesn't seem
        important enough to do.<br>
      </p>
      <p><br>
      </p>
      <p>Chris<br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <div class="moz-cite-prefix">On 8/21/24 2:50 AM, Egor Ushakov
        wrote:<br>
      </div>
      <blockquote type="cite" cite="mid:bb2aa72f-90c7-4b18-8818-88369823c45c@jetbrains.com">
        Hi Chris, <br>
        <br>
        I tried it on jdk 23 and it works the same way :(<br>
        It is clear that calling Thread.interrupted() in debugger should
        modify the interrupted state, but it does not...<br>
        It looks like the debugger is taking thread interrupted state
        from somewhere else, and also somehow calling different
        methods...<br>
        Check the attached video for more details.<br>
        <br>
        Thanks!<br>
        Egor<br>
        <br>
        <div class="moz-cite-prefix">On 20.08.2024 18:27, Chris Plummer
          wrote:<br>
        </div>
        <blockquote type="cite" cite="mid:28938cd9-aaf4-46e5-8857-3ddf40131baa@oracle.com">
          <p>The presence of the breakpoint likely results in the debug
            agent executing code that does a JVMTI RawMonitorWait.
            However, there is code in place in the debug agent to repost
            the interrupt if it happens before or during the wait. See
            the code and comment in debugMonitorWait() and its call to
            handleInterrupt(), which calls
            threadControl_setPendingInterrupt(). It seems this code is
            failing somehow.</p>
          <p><br>
          </p>
          <p>There were changes during JDK 23 in this area for virtual
            thread support, and the changes possibly could impact
            platform threads also. See <a class="issue-link" data-issue-key="JDK-8324868" href="https://bugs.openjdk.org/browse/JDK-8324868" id="key-val" rel="5120243" moz-do-not-send="true">JDK-8324868</a>
            and <a class="issue-link" data-issue-key="JDK-8325187" href="https://bugs.openjdk.org/browse/JDK-8325187" id="key-val" rel="5120651" moz-do-not-send="true">JDK-8325187</a>.
            It would be worth trying with the latest sources to see if
            the issue is still reproducible.</p>
          <p><br>
          </p>
          <p>Regarding calling Thread.currentThread() from the watch
            panel, the use of the JDI method invocation support can
            change the state of the program being debugged. So if you do
            an invoke on the interrupted thread, it would not surprise
            me if the interrupt got cleared as a result, and I think
            this is to be expected.<br>
          </p>
          <p><br>
          </p>
          <p>Chris</p>
          <p><br>
          </p>
          <div class="moz-cite-prefix">On 8/20/24 6:47 AM, Gillespie,
            Oli wrote:<br>
          </div>
          <blockquote type="cite" cite="mid:01000191700af6b8-7ceb0a93-3a3b-44b5-b37d-d52010a0eaa2-000000@email.amazonses.com">
            <style type="text/css" style="display:none;">P {margin-top:0;margin-bottom:0;}</style>
            <div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
              <p>There are lots of paths that clear the interrupted
                flag. In your example, I hit at least this one when
                calling Thread.currentThread from the watch panel:<br>
                <br>
                ```<br>
              </p>
              <div>    at
                java.base/java.lang.Thread.interrupted(Thread.java:1030)<br>
                    at
                java.base/jdk.internal.loader.Resource.getBytes(Resource.java:96)<br>
                    at
java.base/jdk.internal.loader.URLClassPath$JarLoader$2.getBytes(URLClassPath.java:895)<br>
                    at
java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:859)<br>
                    at
java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)<br>
                    at
java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)<br>
                    at
java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)<br>
                    at
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)<br>
                    at
                java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)<br>
                    at java.base/java.lang.Class.forName0(Native Method)<br>
                    at java.base/java.lang.Class.forName(Class.java:467)</div>
              <br>
              ```<br>
              <br>
              but the key for your example seems to be <a href="https://urldefense.com/v3/__https://github.com/openjdk/jdk17u/blob/master/src/hotspot/share/prims/jvmtiRawMonitor.cpp__;!!ACWV5N9M2RV99hQ!LQga2NZfjZKMcpzfXgZa5xyH60muL5xAGlGJHOz7EkcDAjEAT82NT15T3VoPlIUvG59o4exJpW4y9uHOdnIc32D6i4ZQ$" class="OWAAutoLink moz-txt-link-freetext" moz-do-not-send="true">
https://github.com/openjdk/jdk17u/blob/master/src/hotspot/share/prims/jvmtiRawMonitor.cpp</a>.
              If you replace is_interrupted(true) with
              is_interrupted(false) in the 3 calls from that file, your
              example works as you expect. That might help your
              investigations.<br>
              <br>
              Oli<br>
            </div>
            <hr style="display:inline-block;width:98%" tabindex="-1">
            <div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> serviceability-dev <a class="moz-txt-link-rfc2396E" href="mailto:serviceability-dev-retn@openjdk.org" moz-do-not-send="true"><serviceability-dev-retn@openjdk.org></a>
                on behalf of Egor Ushakov <a class="moz-txt-link-rfc2396E" href="mailto:egor.ushakov@jetbrains.com" moz-do-not-send="true"><egor.ushakov@jetbrains.com></a><br>
                <b>Sent:</b> 20 August 2024 13:32:36<br>
                <b>To:</b> serviceability-dev<br>
                <b>Subject:</b> [EXTERNAL] Thread.interrupted() is
                always false in debugger</font>
              <div> </div>
            </div>
            <div>
              <div class="WordSection1">
                <table class="MsoTableGrid" style="border-collapse:collapse;border:none" cellspacing="0" cellpadding="0" border="1">
                  <tbody>
                    <tr style="height:15.25pt">
                      <td style="width:842.35pt;border:solid #ED7D31 1.5pt;padding:0in 5.4pt 0in 5.4pt;height:15.25pt" width="711" valign="top">
                        <p><strong><span style="background:#FFFF99">CAUTION</span></strong><span style="background:#FFFF99">: This email
                            originated from outside of the organization.
                            Do not click links or open attachments
                            unless you can confirm the sender and know
                            the content is safe.</span><o:p></o:p></p>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <br>
              <div>Hi everyone!<br>
                <br>
                we have a long standing issue <a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://youtrack.jetbrains.com/issue/IDEA-169706__;!!ACWV5N9M2RV99hQ!LQga2NZfjZKMcpzfXgZa5xyH60muL5xAGlGJHOz7EkcDAjEAT82NT15T3VoPlIUvG59o4exJpW4y9uHOdnIc30EHSVbp$" moz-do-not-send="true">
                  https://youtrack.jetbrains.com/issue/IDEA-169706</a><br>
                Maybe someone could clarify why it happens and if
                there's a possible workaround.<br>
                Here's the simplified test case:<br>
                <div style="background-color:#ffffff;color:#080808">
                  <pre style="font-family:'Source Code Pro',monospace;font-size:12,0pt;"><span style="color:#0033b3;">public class </span><span style="color:#000000;">Interruption </span>{
    <span style="color:#0033b3;">public static void </span><span style="color:#00627a;">main</span>(<span style="color:#000000;">String</span>[] <span style="color:#000000;">args</span>) {
        <span style="color:#000000;">Thread thread </span>= <span style="color:#000000;">Thread</span>.<span style="font-style:italic;">currentThread</span>();
        <span style="color:#000000;">thread</span>.interrupt();

        <span style="color:#0033b3;">if </span>(<span style="color:#000000;">Thread</span>.<span style="font-style:italic;">interrupted</span>()) { // <----- stop on a breakpoint here 
            <span style="color:#000000;">System</span>.<span style="color:#871094;font-style:italic;">out</span>.println(<span style="color:#067d17;">"Interrupted"</span>);
        } <span style="color:#0033b3;">else </span>{
            <span style="color:#000000;">System</span>.<span style="color:#871094;font-style:italic;">out</span>.println(<span style="color:#067d17;">"Not interrupted"</span>);
        }
    }
}

Obviously the program prints:
<span style="color:#067d17;">Interrupted

</span><font color="#000000">But if stopped on a breakpoint in the debugger, evaluation of </font>
<span style="color:#000000;">Thread</span>.<span style="font-style:italic;">interrupted</span>() always returns false.
More of that <i>interrupted </i>field value in the thread object is also reported as false:
<img alt="" src="cid:part1.r5DlrFSt.nyJyWVdP@oracle.com" class="">

If interrupted method is debugged step by step it is obvious that interrupted value is true, 
but the debugger continue to show it as false.

Any ideas why it could happen and how to fix it?

Thanks!
Egor
</pre>
                </div>
              </div>
            </div>
            <br>
            <br>
            <br>
            Amazon Development Centre (London) Ltd.Registered in England
            and Wales with registration number 04543232 with its
            registered office at 1 Principal Place, Worship Street,
            London EC2A 2FA, United Kingdom.<br>
            <br>
            <br>
          </blockquote>
        </blockquote>
        <br>
      </blockquote>
    </blockquote>
  </body>
</html>