When running our CI tests we have a failure handler registered that will try to 
capture the state of the process when we hit a timeout. It is important to get 
thread dumps when the process hangs, and to make sure that we get one as fast 
as possible we have recently updated the failure handler to start by taking an 
initial Java thread dump.

That all works well for Java-level deadlocks and hangs. However, it doesn't 
work well when it is the JVM that is hanging. When that happens, the requested 
Java thread dump will likely be blocked and time out.

We have two distinct scenarios:

1) The JVM is truly deadlocked trying to reach a global safepoint, or there's a 
deadlock inside a safepoint operation.

jstack and many jcmd actions will hang and time out, one at a time. This takes 
minutes and after that we will proceed to use the native tools to inspect the 
process and dump native stack traces. This scenario is "fine" in the sense that 
we probably will get to the native dumping of stack traces eventually.

2) The JVM is not deadlocked, but something is either taking a very long time 
to reach a safepoint, or there's a safepoint operation that is taking a very 
long time, like a problematic GC verification pass.

In situations like this, the thread dumping and other jcmds will also hang and 
time out, one at a time, until the long operation completes and the test can 
continue to run. When that happens, a few of the jcmds could complete, the test 
could also complete, and the process could move on and exit. If this happens, 
the failure handler doesn't get to the native stack trace dumping, which is 
crucial when debugging JVM hangs.

My proposal is that we make a slight adjustment to the test failure handler and 
make it so that it starts the process inspection by taking one native thread 
dump, before it moves on to take the Java thread dump.

It's worth noting that the JVM process is frozen when we take the native thread 
dump, so the Java code is not running ahead while it is performed. This should 
minimize the risk that we'll miss important information in the Java thread 
dump. This is in contrast to the situation we have when we take the Java thread 
dump, where the JVM can continue running up until the thread dump safepoint 
operation, and some threads will even run non-Java code concurrently with the 
Java thread dumper.

After this change the processes.html shows something like this:

- test_processes
- 5337
    - initial-native-stack
        <The initial native thread stack dump>
    - common
        - thread_dump
            <The Java thread dump>
        - jinfo
        - jcmd
        - ...
    - mac
        - ...
        - stack
            - iteration_0
                <Native thread stack dump>
            - iteration_1
            - ...
        - ...


The `sectionPathOverride` part of the patch makes it so that the we don't get 
something simlar to this:

- 5337
    - mac-initial-native-stack
        - stack
            - iteration_0
                <The initial native thread stack dump>
    - ...


Testing of this has been manually triggering timeouts on Linux, Mac, and 
Windows.

---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

-------------

Commit messages:
 - 8395909: Make the test failure_handler take an early native thread stack dump

Changes: https://git.openjdk.org/jdk/pull/33591/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=33591&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8395909
  Stats: 155 lines in 5 files changed: 152 ins; 0 del; 3 mod
  Patch: https://git.openjdk.org/jdk/pull/33591.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/33591/head:pull/33591

PR: https://git.openjdk.org/jdk/pull/33591

Reply via email to