Skip to content

Instantly share code, notes, and snippets.

@kany
Last active June 22, 2020 12:37
Show Gist options
  • Save kany/5363792 to your computer and use it in GitHub Desktop.
Save kany/5363792 to your computer and use it in GitHub Desktop.
Using GDB to inspect a running Ruby process

http://robots.thoughtbot.com/post/47202759358/using-gdb-to-inspect-a-running-ruby-process

That’s not a great thing to have to say, is it? However, I bet you’ve said it before and may not have immediately know why.

With liberal use of puts and maybe pry, you can figure out what a problem might be next time you run it, but sometimes you need to figure out what that problem is right now.

As it turns out, and I know this is a shocker, Ruby processes are just regular processes. They can be debugged with gdb.

Having recently had the need to find out why a job of mine was running particularly slowly, I found out about this lovely tool the hard way: frantic googling. I found some very useful functions for gdb in a blog post by Rasmus on Ruby callstacks.

define redirect_stdout
  call rb_eval_string("$_old_stdout, $stdout = $stdout, File.open('/tmp/ruby-debug.' + Process.pid.to_s, 'a'); $stdout.sync = true")
end

define ruby_eval
  call(rb_p(rb_eval_string_protect($arg0,(int*)0)))
end

How to use these:

Start up gdb by running gdb /path/to/ruby PID, where /path/to/ruby is the full path to the actual ruby binary and PID is the process ID of the ruby you want to check out. Paste those functions above into the gdb prompt (you might also want to store them in ~/.gdbinit for later). Run redirect_stdout``, which will put all the ruby output into a file called /tmp/ruby-debug.PIDwhere PID in this case if the process id of gdb — not terribly important, but a differentiator in case you do this a lot. Run commands viaruby_eval('Kernel.caller')``` and object_id and things like that. You should be able to get local variables from wherever you broke into the program. These ruby_eval commands will output into the tempfile that redirect_stdout created, so you’ll need to tail -f that file in a different console. Now, with that small headache over with, you can see exactly where your program is and if there is a stupid loop where you forgot to check a boundary condition, or what thing you’re doing with a regular expression on where you should have just used String#index.

Written by Jon Yurek.

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