# 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

## config

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:

• dump_page - takes an address of a heap page as an argument and dumps a list of the contents of every slot on that page
• dump_page_rvalue - same as the above but takes an RVALUE * and dumps the page containing that RVALUE
• heap_page - takes either an RVALUE * or a heap_page * as argument and prints out information about the page. Basically finds and dereferences a heap_page *

• most things can be abbreviated, b == breakpoint, f == frame etc
• bt prints the backtrace
• frame n where n is an integer, jumps to stack frame n
• frame variable prints a list of the locals in the current stack frame
• source list (or just f) shows you where you are

## setting breakpoints

The recommended way is either:

• breakpoint set --name some_function_name or
• breakpoint set --file io.c --line 1234

But these can be abbreviated to

• b some_function_name
• b io.c:1234

## 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]