Pony LLDB Cheat Sheet¶
Setup¶
macOS Setup¶
% brew install llvm
% sudo /usr/sbin/DevToolsSecurity --enable
Basics¶
Official LLDB tutorial¶
http://lldb.llvm.org/tutorial.html
GDB ↔ LLDB Rosetta Stone¶
http://lldb.llvm.org/lldb-gdb.html
Building an Executable You Can Debug¶
% ponyc --debug
Running an Executable¶
% lldb EXECUTABLE -- arg1 arg2 arg3 …
% lldb -- EXECUTABLE arg1 arg2 arg3 ...
(lldb) run
Setting Breakpoints¶
(lldb) breakpoint set --file foo.c --line 12
(lldb) breakpoint set --name foo
(lldb) b foo.c:12
(lldb) b Main_create
(lldb) b map.pony:73
When using a file name/line combination to set the breakpoint, you can specify any file in the program without having to specify a path to that file, as long as the file name is unambiguous.
List Breakpoints¶
(lldb) breakpoint list
(lldb) b
Backtrace¶
(lldb) thread backtrace
(lldb) bt
If you would like to limit the size of the backtrace (for example, when you are debugging a case of runaway recursion that blows out the stack and generates a very long backtrace), you can use the --count
or -c
option to specify the number of frames to print, starting with the most recent one.
(lldb) thread backtrace --count 5
(lldb) bt 5
Stepping¶
(lldb) thread step-in
(lldb) s
(lldb) sif funToStepInto
(lldb) thread step-over
(lldb) n
(lldb) thread step-out
(lldb) finish
(lldb) thread until LINE
Frame¶
Select a frame:
(lldb) frame select NUMBER
(lldb) f NUMBER
Show the variables in the current frame:
(lldb) frame variable
Show a specific variable from the current frame:
(lldb) frame variable VARIABLE
(lldb) p VARIABLE
Pointer, array, structure, and cast operation from C can be applied to frame variables.
&variable : address of a variable
*variable : dereference a pointer
variable.field : access a field within a structure
pointer_variable->field : access a field within a structure pointed to by a pointer
array_pointer[index] : access an index within an array
(type_t *)variable : cast variable to a pointer to a type_t
Examples¶
Example: Examining an object¶
(lldb) frame variable
(OscMessage *const) this = <variable not available>
(Array_U8_val *) parts = 0x0000000108fcf4c0
(OscString *) oscAddress = <variable not available>
(OscString *) types = 0x00007fff5fbff878
(lldb) frame variable *types
(OscString) *types = {
_data = 0x0000000108fcf560
}
(lldb) frame variable *types->_data
(String) *types->_data = (_size = 2, _alloc = 3, _ptr = ",f")
(pony_test_TestHelper *) this = 0x0000000110ff5020
(lldb) p this
(pony_test_TestHelper *) $2 = 0x0000000110ff5020
(lldb) p *$2
(pony_test_TestHelper) $3 = {
_runner = 0x0000000110ff7200
env = 0x0000000108ffec00
}
(lldb) p $3.env
(Env *) $4 = 0x0000000108ffec00
(lldb) p *$4
(Env) $5 = {
root = 0x000000010004f3e0
input = 0x0000000108fd6800
out = 0x0000000108fff500
err = 0x0000000108fff600
args = 0x0000000108fd6400
_envp = 0x00007fff5fbffa98
_vars = 0x000000010004f3b0
}
Using p
lets you work from the resulting lldb temporary variables, which can be very convenient when you want to examine an intermediate result.
Example: Printing A String¶
Assume you have a Pony String called x
. You can print the string like this:
(lldb) p (char *)(x->_ptr)
(char *) $3 = 0x00000001000106f8 "abc"
(lldb)
Example: Printing The Values In An Array Of Numbers¶
Assume you have an Array[U64]
called x
with 6 elements. You can print the values of the values of the elements like this:
(lldb) p *(long(*)[6])(x->_ptr)
(long [6]) $3 = ([0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = 6)
You can adjust the type (long
) to appropriately print the types that correspond to the array values, and adjust the size (6
) to print more or fewer of the elements.
Pony Stuff¶
Method Name Mangling¶
{{< warning title=”Future breakage possible!” >}} While currently necessary for some debugging, you should know that name mangling might change in the future. Do not depend on this remaining static. {{< /warning >}}
Method names get mangled by the compiler. The general format for the mangling is:
<package_>type<_typearg1_typearg2>_rcap_methodname_mangling
In the above:
package
: the name of the package (for methods brought in through use expressions)
type
: the name of the type to which the method belongs
typearg1, typearg2
…
: the type parameters of the method (for methods that use type parameters)
rcap
: the reference capability of the method
methodname
: the name of the method
mangling
: a mangling string where each character indicates the type of each method parameter and the method’s return type according to the following conversion:
Type | Mangling |
---|---|
object |
o |
Bool |
b |
I8 |
c |
I16 |
s |
I32 |
i |
I64 |
w |
I128 |
q |
ILong |
l |
ISize |
z |
U8 |
C |
U16 |
S |
U32 |
I |
U64 |
W |
U128 |
Q |
ULong |
L |
USize |
Z |
F32 |
f |
F64 |
d |
These rules can be used to determine the name of function in order to specify that you would like to place a breakpoint on it. You can also type b <characters><tab>
to see a tab-complete list of all the available functions that start with <characters>
. To set a breakpoint on a function:
(lldb) breakpoint set --name Bar_foo
(lldb) b Bar_foo
Calling Methods¶
As of April 5, 2017, issue #1813 is preventing this from working.
Behaviors and Messages¶
Each behavior has an associated send method (