Skip to content

Instantly share code, notes, and snippets.

@wr0ngway
Last active March 14, 2023 11:02
Show Gist options
  • Save wr0ngway/3001d76b4e5bf312e912 to your computer and use it in GitHub Desktop.
Save wr0ngway/3001d76b4e5bf312e912 to your computer and use it in GitHub Desktop.
Uses gdb to dump ruby backtraces for all threads, and displays them in an easily readable format
#!/bin/bash
PID=$1
RUBY_BINARY=`which ruby`
BT_FILENAME="/tmp/ruby-backtrace-$PID-$(date +%s).txt"
cmdfile=$(mktemp)
cat <<EOF > $cmdfile
set \$old_stdout = dup(1)
set \$old_stderr = dup(2)
set \$fd = creat("$BT_FILENAME", 0644)
call dup2(\$fd, 1)
call dup2(\$fd, 2)
set \$thread_list = rb_thread_list()
set \$num_threads = rb_num2long(rb_ary_length(\$thread_list))
set \$i = 0
while \$i < \$num_threads
call rb_p(rb_thread_backtrace_m(0, 0, rb_ary_entry(\$thread_list, \$i++)))
end
call dup2(\$old_stdout, 1)
call dup2(\$old_stderr, 2)
call close(\$old_stdout)
call close(\$old_stderr)
call close(\$fd)
EOF
gdb "$RUBY_BINARY" "$PID" -batch -x $cmdfile &> /dev/null
ruby -e 'ARGF.each {|l| val = eval(l); puts val ? val.join("\n") : "nil thread"; puts "\n\n\n\n" }' $BT_FILENAME
@guymaliar
Copy link

@wr0ngway, this is awesome!
I changed RUBY_BINARY to rbenv which ruby and it worked well.

@hyperair
Copy link

On Linux, changing RUBY_BINARY to /proc/$PID/exe may yield more accurate results if you have many ruby binaries floating around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment