Debugging a simple program with LLDB

Debugging a simple program with LLDB
Sample C++ code, let’s call it test.cpp.

#include <iostream>
#include <string>

typedef struct goo {
	int gooInt;
	std::string gooString;
}GOO;

int main(void)
{
	GOO myGOO;
	myGOO.gooInt = 42;
	myGOO.gooString = "answer";

	int myVar = 5;
	for (int i = 0; i < 10; i++)
		myVar += i;

	return(0);
}

Use “-g” flag to enable extra debugging information.

oz@LynxGwyn:~/sample_lldb$ clang++ -g test.cpp -o test 

Attach the debugger.

oz@LynxGwyn:~/sample_lldb$ lldb test 

Set a breakpoint to the main()

(lldb) b main 
 Breakpoint 1: where = test main + 19 at test.cpp:12, address = 0x0000000000400a53 

you can use this syntax to set a breakpoint to other functions as well. (e.g “lldb b foo”)

Start the process

(lldb) run 
Process 7254 stopped
* thread #1: tid = 7254, 0x0000000000400a53 test main + 19 at test.cpp:11, name = 'test', stop reason = breakpoint 1.1
    frame #0: 0x0000000000400a53 test main + 19 at test.cpp:11
   8   	
   9   	int main(void)
   10  	{
-> 11  		GOO myGOO;
   12  		myGOO.gooInt = 42;
   13  		myGOO.gooString = "answer";
   14  	

To set a breakpoint on individual lines.

(lldb) b *lineno*

or

(lldb) b *filename.cpp:lineno* 
(lldb) b 16 

or

(lldb) b test.cpp:16 
 Breakpoint 2: where = main + 63 at test.cpp:16, address = 0x0000000000400a7f 

To list the currently set breakpoints

(lldb) breakpoint list 
Current breakpoints:
1: name = 'main', locations = 1, resolved = 1, hit count = 1
  1.1: where = test main + 19 at test.cpp:11, address = 0x0000000000400a53, resolved, hit count = 1 

2: file = '/home/oz/gl/test.cpp', line = 16, exact_match = 0, locations = 1, resolved = 1, hit count = 1
  2.1: where = test main + 63 at test.cpp:16, address = 0x0000000000400a7f, resolved, hit count = 1 

Use

(lldb) c

twice to continue until second break point

To get the current local variable values

(lldb) frame variable 

or simply

(lldb) fr var 
(GOO) myGOO = (gooInt = 42, gooString = "answer")
(int) myVar = 5
(int) i = 0

To get an individual variable’s value

(lldb) frame var myGOO 
(GOO) myGOO = (gooInt = 42, gooString = "answer")

You can use *watchpoints* to stop the execution when a value changes

(lldb) watch set var myVar 



watchpoint created: Watchpoint 1: addr = 0x7fffffffdd70 size = 4 state = enabled type = w
    declare @ '/home/oz/gl/test.bash:15'
    watchpoint spec = 'myVar'
    new value: 5

To set a stopping condition

(lldb) watch modify -c '(myVar>9)' 

Use "c" to continue until the "myVar" reaches above 9

Process 7430 resuming

Watchpoint 1 hit:
old value: 5
new value: 11
Process 7430 stopped
* thread #1: tid = 7430, 0x0000000000400a99 test main + 89 at test.bash:16, name = 'test', stop reason = watchpoint 1
    frame #0: 0x0000000000400a99 test main + 89 at test.bash:16
   13  		myGOO.gooString = "answer";
   14  	
   15  		int myVar = 5;
-> 16  		for (int i = 0; i < 10; i++)
   17  			myVar += i;
   18  	
   19  		return(0);

Use "watchpoint list" or "watch l" to get the currently set watchpoints

Current watchpoints:
Watchpoint 1: addr = 0x7fffffffdd70 size = 4 state = enabled type = w
    declare @ '/home/oz/gl/test.bash:15'[I'm an inline-style link](https://www.google.com)
    watchpoint spec = 'myVar'
    old value: 5
    new value: 11
    condition = '(myVar>9)'

Enter "watch del 1" to delete the watchpoint

 1 watchpoints deleted. 

Enter "c" to finish the execution!

 Process 7576 resuming
Process 7576 exited with status = 0 (0x00000000) 

Congrats!

Additional Sources:

https://lldb.llvm.org/lldb-gdb.html

https://lldb.llvm.org/tutorial.html