(2011) (Session 321) Migrating From GDB To LLDB
(2011) (Session 321) Migrating From GDB To LLDB
Session 321
Jim Ingham
Senior Debugger Engineer
These are confidential sessions—please refrain from streaming, blogging, or taking pictures
1
Talk Outline
■ Command aliases
2
What is the LLDB Project?
■ http://lldb.llvm.org
• Makes use of the clang parser for type system and expression evaluation
• Very efficient handling of debug info (incremental DWARF parser)
■ Faster startup times, lower memory usage
• Threads are first class citizens
• Powerful scripting component (using Python)
3
What is LLDB?
4
Console LLDB
localhost> ./lldb Sketch.app
Current executable set to '/tmp/Sketch.app/' (x86_64).
(lldb) b alignLeftEdges:
breakpoint set --name 'alignLeftEdges:'
Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1
(lldb) run
Process 16704 launched: '/tmp/Sketch.app/Contents/MacOS/
Sketch' (x86_64)
...
5
Console LLDB
Process 16704 stopped
* thread #1: SKTGraphicView.m:1405, stop reason = breakpoint 1.1
frame #0: 0x0000000100017b77 SKTGraphicView.m:1405
1402!
1403!
1404!- (IBAction)alignLeftEdges:(id)sender {
-> 1405! NSArray *selection = [self selectedGraphics];
1406! NSUInteger i, c = [selection count];
1407! if (c > 1) {
1408! NSRect firstBounds = [[selection objectAtIndex:0] bounds];
(lldb) po self
(SKTGraphicView *) $1 = 0x0000000102115580 <SKTGraphicView: 0x102115580>
(lldb) n
Process 16704 stopped
6
LLDB Command Syntax
7
Basic Syntax
• Commands are in the form:
■ object action [options] [arguments]
breakpoint set --name main
8
Basic Syntax
• Commands are in the form:
■ object action [options] [arguments]
breakpoint set --name main
breakpoint delete 5
object actionargument
9
Basic Syntax
• Commands are in the form:
■ object action [options] [arguments]
breakpoint set --name main
breakpoint delete 5
■ Options have short and long form, can appear anywhere
target create MyApp.app -a i386
10
Basic Syntax
• Commands are in the form:
■ object action [options] [arguments]
breakpoint set --name main
breakpoint delete 5
■ Options have short and long form, can appear anywhere
target create MyApp.app -a i386
■ “--” ends options (useful if arguments start with “-”)
process launch --working-dir /tmp -- -run-arg-1 -run-arg-2
11
Basic Syntax
• Commands are in the form:
■ object action [options] [arguments]
breakpoint set --name main
breakpoint delete 5
■ Options have short and long form, can appear anywhere
target create MyApp.app -a i386
■ “--” ends options (useful if arguments start with “-”)
process launch --working-dir /tmp -- -run-arg-1 -run-arg-2
■ Words are white-space separated
■ Use quotes to protect spaces, “\” to protect quotes.
■ Some commands are “unparsed” after the end of options:
■ “expression” and “script”
12
Basic Syntax
13
Help
• “help” command for detailed explanation of command/subcommand
(lldb) help breakpoint delete
Delete the specified breakpoint(s). If no breakpoints are specified,
delete them all.
14
LLDB Command Objects
15
LLDB Command Objects
thread list
■ “select” will focus on one instance
thread select 1
■ Auto-selected when that makes sense
■ e.g., if you stop at a breakpoint, process, thread and frame are set
■ Some object are contained in others (frame in thread)
■ Selecting a thread sets the context for selecting a frame…
16
LLDB Command Objects
• The object/action form makes it easy to find commands
• For example, how do you do a backtrace?
■ Break it into an object and an action
■ First figure out which object would be responsible
17
Brief Tour of Objects—Target
18
Brief Tour of Objects—Process
19
Brief Tour of Objects—Thread
20
Brief Tour of Objects—Frame
21
Brief Tour of Objects—Register
22
Brief Tour of Objects—Register
Look up
functions
23
Aliases
• Having a regular command set makes it easy to learn and find things
• But there must be accelerators for common commands
• By default, LLDB ships with a “GDB-like” set of aliases
■ Listed in “help “ after the built-in commands
• But you may find you have some other combination you use often
• Two kinds of short-cuts are possible:
■ Positional aliases
■ Regular expression aliases (power-user!)
24
Positional Aliases
25
Positional Aliases
26
Alias for More Than One Behavior
• But in C addresses are not hard to tell from names (0x vs. [a-zA-Z_])
• Can we do:
■ If there is one argument, beginning with 0x, that’s a start address
■ Otherwise if there is one argument it is the function name
27
Regexp Aliases—Syntax
28
Regexp Aliases—Patterns
• No arguments:
s/^$/disassemble --pc -c 20/
• Passthrough:
s/^(.*)$/disassemble %1/
29
Regexp Aliases—Final Result
• Altogether:
(lldb) command regex dfancy --help “disassemble by hex address or name”
Enter regular expressions in the form 's/<regex>/<subst>/'
and terminate with an empty line:
s/^(0x[0-9a-fA-F]+)$/disassemble -s %1 -c 20/ Address
s/^([^0][^x][^ ]*)$/disassemble -n %1 -c 20/ Function name
s/^$/disassemble -p -c 20/ No arguments
s/^(.*)$/disassemble %1/ Route to base command
30
Summary
31
Running Code Inside Your Program
Introducing the Expression Parser
Sean Callanan
AST Wrangler
32
The Basics
Programming in the current context
33
The Basics
Programming in the current context
Program local variable
Usable if it’s in scope
int main ()
{
struct list_entry list;
init_list(&list);
insert_before(0, “Zero”, &list);
insert_before(1,
{ “One”, &list);
insert_before(2,
list.key; “Two”, &list);
(lldb) expr list.key }
free_list(&list);
}
34
The Basics
Programming in the current context
int main ()
{
struct list_entry list;
Multi-line expression init_list(&list);
Press Enter after expr;
blank line terminates
insert_before(0, “Zero”, &list);
insert_before(1,
{ “One”, &list);
(lldb) expr insert_before(2,
int i = 3; “Two”, &list);
Expression local variable
int i = 3; free_list(&list);
i + 2;
Usable inside the expression,
disappears afterward
i + 2; } }
35
The Basics
Programming in the current context
36
The Basics
Programming in the current context
class MyClass {
public:
{
MyClass(int i) : m_i(i) { }
int m_i++;
GetI() {
(lldb) expr m_i++ }
return m_i;
}
private:
int m_i;
C++ member variable
} Usable inside a class
37
The Basics
Programming in the current context
38
The Basics
Summary—What you can access
• In-scope variables: expr m_i
• Globals and functions with debug info: expr myfunc()
• Global symbols without debug info (casts required)
■ Functions: expr (int)strlen(“Hello world!”)
■ Variables: expr (char**)environ
39
Example
Debugging an RPN calculator
> 7
> 5
> +
12
40
Example
Debugging an RPN calculator
> 7
> 5
> + 12
5
7
12 Stack base
41
Example
Debugging an RPN calculator
> 7
> +
Segmentation
fault
42
Example
Inspect the stack, read variables
$ lldb rpn
Current executable set to 'rpn' (x86_64).
(lldb) run
Process 3088 launched: 'rpn' (x86_64)
> 7
> +
Process 3088 stopped No debug information!
… At add+33, args could
be anywhere.
(lldb) bt
* thread #1: … stop reason = EXC_BAD_ACCESS …
frame #0: 0x0000000100000e11 rpn`add + 33
frame #1: 0x0000000100000ce7 rpn`main + 343
frame #2: 0x0000000100000b84 rpn`start + 52
43
Example
Plan B: Read arguments from registers
(lldb) b add
(lldb) run
There is a running process, kill it and
restart?: [Y/n] yes
> 7
> +
Process 3088 stopped At the entry point
… Now, arguments are
available in registers.
(lldb) bt
* thread #1 … stop reason = breakpoint 1.1
frame #0: 0x0000000100000df0 rpn`add
frame #1: 0x0000000100000ce7 rpn`main + 343
frame #2: 0x0000000100000b84 rpn`start + 52
44
Example
Plan B: Read arguments from registers
45
Example
Fix the problem
46
Example
Compute the depth of the stack
> 3
> 5
> + Type definitions are scoped
Process 3088 stopped If you create new variables,
redeclare the type.
(lldb) expr
struct s { struct s *next; long long value; };
int depth = 0;
for (struct s *current = *((struct s**)$arg1);
current != 0;
current = current->next)
depth++;
depth;
(int) $5 = 2
47
Summary
48
Migrating from GDB to LLDB
Scripting and Python in LLDB
Caroline Tice
Debugger Engineer
49
What Can You Do with Scripting in LLDB?
■ By thread
50
What Can You Do with Scripting in LLDB?
51
What Can You Do with Scripting in LLDB?
52
What Can You Do with Scripting in LLDB?
53
What is Where?
LLDB
Python
54
What is Where?
LLDB Python
Python LLDB
AND
55
LLDB in Python (Directly)
% setenv PYTHONPATH \
/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
% python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lldb
>>> dbg = lldb.SBDebugger.Create()
>>> target = dbg.CreateTarget (“/bin/ls”)
>>> target.BreakpointCreateByName (“main”)
>>> process = target.LaunchSimple (None, None, None)
56
LLDB in Python (Directly)
% setenv PYTHONPATH \
/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
% python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lldb
>>> dbg = lldb.SBDebugger.Create()
>>> target = dbg.CreateTarget (“/bin/ls”) LLDB API
>>> target.BreakpointCreateByName (“main”) function calls
>>> process = target.LaunchSimple (None, None, None)
57
LLDB in Python (Directly)
% setenv PYTHONPATH \
/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
% python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lldb
>>> dbg = lldb.SBDebugger.Create()
>>> target = dbg.CreateTarget (“/bin/ls”)
>>> target.BreakpointCreateByName (“main”)
>>> process = target.LaunchSimple (None, None, None)
58
Python in LLDB
■ Breakpoint commands
59
Python in LLDB
■ Breakpoint commands
60
Python in LLDB
■ Breakpoint commands
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>>
61
Python in LLDB
■ Breakpoint commands
62
LLDB Scripting/Python Enhancements
• API functions
■ Create, access and manipulate debugger objects and state
63
Part 2—Scripting in Action
Using scripting in LLDB to find a bug…
64
Example: Simple Dictionary Program
Store and find words in Binary Search Tree
“migrate”
“debug” “programs”
65
Problem: Word is Not Found in Dictionary
$ ./dictionary Romeo-and-Juliet.txt
Dictionary loaded.
Enter search word: love
Yes!
Enter search word: sun
Yes!
Enter search word: Romeo
No!
66
Problem: Word is Not Found in Dictionary
67
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
68
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB User-created file
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
69
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
70
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
71
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
72
The Plan
(Searching tree without restarting program)
• Write Depth-First Search (DFS) function in file (tree_utils.py)
■ “define DFS (root, word, cur_path): …”
• Attach to running program with LLDB
• Use interactive interpreter to call DFS on existing tree
• DFS function returns root-to-node path, if found
73
Using the Interactive Interpreter
74
Using the Interactive Interpreter
LLDB convenience
variable (current frame)
75
Using the Interactive Interpreter
76
Using the Interactive Interpreter
77
Using the Interactive Interpreter
78
Using the Interactive Interpreter
79
We’re Halfway There...
The problem
Our word
80
Python Breakpoint Command
(At decision to follow right child)
def obscure_func_name
Enter (frame, bp_loc):
your Python command(s). Type ‘DONE’ to end.
> global path
> if path[0] == 'R':
> path = path[1:]
> thread = frame.GetThread()
> process = thread.GetProcess()
> process.Continue()
> else:
> print "Going right, should go left!"
> DONE
81
Python Breakpoint Command
(At decision to follow right child)
def obscure_func_name (frame, bp_loc):
global path
if path[0] == 'R': LLDB convenience variables
path = path[1:]
thread = frame.GetThread()
process = thread.GetProcess()
process.Continue()
else:
print "Going right, should go left!"
82
Python Breakpoint Command
(At decision to follow right child)
global path
if path[0] == 'R':
path = path[1:]
thread = frame.GetThread()
process = thread.GetProcess()
process.Continue()
else:
print "Going right, should go left!"
83
Python Breakpoint Command
(At decision to follow right child)
global path
if path[0] == 'R':
path = path[1:]
thread = frame.GetThread() LLDB convenience
process = thread.GetProcess() variable
process.Continue()
else:
print "Going right, should go left!"
84
Python Breakpoint Command
(At decision to follow right child)
global path
if path[0] == 'R':
path = path[1:]
thread = frame.GetThread() LLDB API
process = thread.GetProcess() function calls
process.Continue()
else:
print "Going right, should go left!"
85
Results…
(lldb) breakpoint command add --script-type python 1
...
(lldb) breakpoint command add --script-type python 2
...
(lldb) continue
Going right; should go left!
Process 236 stopped
...
(lldb) expr root->word
(const char *) $0 = “dramatis”
(lldb) expr search_word
(char *) $1 = “romeo”
(lldb) script print path
LLRRL
(lldb) expr root->left->left->right->right->left->word
(const char *) $2 = “Romeo”
(lldb)
Case conversion problem!
86
Summary
87
LLDB in Review
■ Aliases
• Expression Parser
■ Executing code inside your program
■ Debugging without debug info
88
For Further Reference
• Information on the LLDB website
■ General info about LLDB (http://lldb.llvm.org)
■ Tutorial for GDB->LLDB transition (http://lldb.llvm.org/tutorial.html)
89
More Information
Michael Jurewitz
Developer Tools and Performance Evangelist
[email protected]
90
Related Sessions
Pacific Heights
Effective Debugging with Xcode 4 Friday 9:00AM
91
92