Sunday, March 02, 2025

Overcoming stubborn jstack

Situation: Need to peek into what the different threads of a Java process are doing. But when running jstack, something the following happens after a little while:

target process 1985458 doesn't respond within 10500ms or HotSpot VM not loaded

You could try adding the "-F" flag to jstack, but often it will not work, because of jstack's timeout.

One way to handle this is to create a core dump of the Java process and then running "jhsdb jstack ..." on the resulting core file. Since jhsdb does not have a timeout, this makes a difference.

To generate the core file on Linux, you first need to install gdb on the server, if it's not already around. Then, assuming the Java process ID is 54321:

gdb -p 54321

In the gdb shell, run:

generate-core-file

You should now have a file "core.54321".

Things which may cause trouble for core file generation:

  • When running gdb, your current working directory is on a file system which is too small, or you don't have write permissions.
  • Your login session has limits on the size of core files. For this, run "ulimit -c unlimited".

My experience is that core file generation will not cause the process to fail (if you answer yes to leave the process running when exiting gdb), but it will freeze, while the core file is being created.

Now, having produced a core file, analyze it without a timeout (it can take a long time, depending on the size of the Java process). One long command line:

jhsdb jstack --exe /usr/lib/jvm/java-17-openjdk-amd64/bin/java --core core.54321 > output.txt

Of course, you may need to adjust the path to the Java which was used by process 54321.