Lldb Tips

Here are some things I’ve learned about using the lldb debugger.

Getting started

Always compile Ruby with -g -O0 (see [building-ruby]). This disables optimisations and compiles with debug information so that stacktraces are much more easily readable.

When you’re in the lldb shell. start the process with process launch, or run, or r. This will run until the end (or a crash or breakpoint).

You can tell lldb to stop at the beginning of the program by using --stop-at-entry as an argument to the run command


Add this to your ~/.lldbinit

type format add --format hex VALUE
command script import -r ~/src/ruby/ruby/misc/lldb_cruby.py

This will always display VALUE objects in hex, which is easier to read. especially as these are often memory locations.

It also pulls in the Ruby lldb helpers which gives you rp which allows you to print out detailed information about any VALUE pointer’s by checking the type of the data referenced by the pointer and then interpreting the struct.

Some of the functions I use most often defined in the lldb ruby helpers are:

basic navigation

setting breakpoints

The recommended way is either:

But these can be abbreviated to

running expressions

You can run expressions using expr or p. This is useful to look at variables, or check truthiness of stuff.

Some examples:

(lldb) p objspace->flags
(rb_objspace::(anonymous struct)) $7 = {
  mode = 0
  immediate_sweep = 1
  dont_gc = 0
  dont_incremental = 0
  during_gc = 0
  during_compacting = 0
  gc_stressful = 0
  has_hook = 0
  during_minor_gc = 0
  during_incremental_marking = 0
(lldb) p objspace->flags.mode == 1
(bool) $8 = false

In both of these cases you can see lldb has saved the result of the expression to a register as well as printing it out (the $7 in the first example and the $8 in the second). These are sequentially incrementing for the life of your lldb session starting at $0.

You can refer to them again in other expressions.

(lldb) p $7.mode == $8
(bool) $10 = true

Inspecting CRuby objects

Here is an example of dealing with VALUE objects and inspecting internal Ruby structures in lldb: [ruby-inspecting-structs-lldb]