Quickly Jumping to Crashing Thread in OpenJDK with GDB
I have been hacking on OpenJDK for some years now. It is very easy to cause the VM to explode (intentionally or unintentionally) so I have spent a lot of time in GDB debugging it. With the flag -XX:+ShowMessageBoxOnError
the JVM will ask you if you want to jump into a GDB session if a crash occurs. Many applications may create a lot of threads, but even the VM will have a bunch of them (the more cores, the more threads it would use). To find the thread that caused the crash one needs to find the frame that has __GI___wait4
. Until recently I did this process manually, then I realized that there should be a better way.
Asking ChatGPT it turns out that GDB has some Python bindings allowing us to automate this process.
Step (1) create a file switch_to_crash_thread_jvm.gdb
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
python
import gdb
class SwitchThread(gdb.Command):
def __init__(self):
super().__init__("jdk", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
pagination_setting = gdb.parameter("pagination")
gdb.execute("set pagination off")
threads = gdb.selected_inferior().threads()
for thread in threads:
gdb.execute("thread {}".format(thread.num))
frame = gdb.selected_frame()
if frame.name() == "__GI___wait4":
print("Switched to thread {}".format(thread.num))
break
gdb.execute("set pagination on")
SwitchThread()
end
Step (2) add to your ~/.gdbinit
file source /home/jonas/.gdb/switch_to_crash_thread_jvm.gdb
.
Next time the JVM crashes you can type jdk
in GDB to quickly jump to the thread that caused the crash. Pretty neat!
Disclaimer: As I did this during an exploration of the limitations of ChatGPT the above code was generated by it. ChatGPT is so far not a good coder, as I needed to give it a lot of follow-up instructions for it to be able to produce correct code. In hindsight, it would have been faster to just look at the documentation.