Short example of degugging with LLDB.
As an example, I will use a small program that I wrote for Rosetta Code:
const std = @import("std");
const stdout = @import("std").io.getStdOut().writer();
pub fn rot(txt: []u8, key: u8) void {
for (txt, 0..txt.len) |c, i| {
if (std.ascii.isLower(c)) {
txt[i] = (c - 'a' + key) % 26 + 'a';
} else if (std.ascii.isUpper(c)) {
txt[i] = (c - 'A' + key) % 26 + 'A';
}
}
}
pub fn main() !void {
const key = 3;
var txt = "The five boxing wizards jump quickly".*;
try stdout.print("Original: {s}\n", .{txt});
rot(&txt, key);
try stdout.print("Encrypted: {s}\n", .{txt});
rot(&txt, 26 - key);
try stdout.print("Decrypted: {s}\n", .{txt});
}
Now letβs compile:
zig build-exe caesar.zig
Start debugging:
lldb caesar
(lldb) target create "caesar"
Current executable set to '/home/chris/workspace/zig/rosetta/caesar' (x86_64).
(lldb) β
Now we set a breakpoint at main function:
(lldb) b main
Breakpoint 1: where = caesar`caesar.main + 18 at caesar.zig:16:5, address = 0x0000000001033c22
(lldb) β
And then run the program:
(lldb) r
Process 24175 launched: '/home/chris/workspace/zig/chris/usb/caesar' (x86_64)
Process 24175 stopped
* thread #1, name = 'caesar', stop reason = breakpoint 1.1
frame #0: 0x0000000001033c22 caesar`caesar.main at caesar.zig:16:5
13
14 pub fn main() !void {
15 const key = 3;
-> 16 var txt = "The five boxing wizards jump quickly".*;
17
18 try stdout.print("Original: {s}\n", .{txt});
19 rot(&txt, key);
(lldb) β
We can step forward with next:
(lldb) n
Process 24175 stopped
* thread #1, name = 'caesar', stop reason = step over
frame #0: 0x0000000001033c43 caesar`caesar.main at caesar.zig:18:21
15 const key = 3;
16 var txt = "The five boxing wizards jump quickly".*;
17
-> 18 try stdout.print("Original: {s}\n", .{txt});
19 rot(&txt, key);
20 try stdout.print("Encrypted: {s}\n", .{txt});
21 rot(&txt, 26 - key);
(lldb) β
And so on. A very nice feature is switching to GUI mode:
(lldb) gui
| LLDB (F1) | Target (F2) | Process (F3) | Thread (F4) | View (F5) | Help (F6) |
βββ<Sources>ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ<Threads>ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β caesar`caesar.main ββ ββprocess 24175 β
β 1 β const std = @import("std"); ββ ββββthread #1: tid = 0x5e6f, stop reason = step over β
β 2 β const stdout = @import("std").io.getStdOut().writer(); ββ ββ#0: caesar.main + 51 β
β 3 β ββ ββ#1: start.posixCallMainAndExit [inlined] start.callMain +β
β 4 β pub fn rot(txt: []u8, key: u8) void { ββ ββ#2: start.posixCallMainAndExit + 93 β
β 5 β for (txt, 0..txt.len) |c, i| { ββ ββ#3: start.posixCallMainAndExit + 1133 β
β 6 β if (std.ascii.isLower(c)) { ββ ββ#4: start._start + 18 β
β 7 β txt[i] = (c - 'a' + key) % 26 + 'a'; ββ β
β 8 β } else if (std.ascii.isUpper(c)) { ββ β
β 9 β txt[i] = (c - 'A' + key) % 26 + 'A'; ββ β
β 10 β } ββ β
β 11 β } ββ β
β 12 β } ββ β
β 13 β ββ β
β 14 β pub fn main() !void { ββ β
β 15 β const key = 3; ββ β
β 16 β var txt = "The five boxing wizards jump quickly".*; ββ β
β 17 β ββ β
β 18 ββ try stdout.print("Original: {s}\n", .{txt}); <<< Thread 1: step overββ β
β 19 β rot(&txt, key); ββ β
β 20 β try stdout.print("Encrypted: {s}\n", .{txt}); ββ β
β 21 β rot(&txt, 26 - key); ββ β
β 22 β try stdout.print("Decrypted: {s}\n", .{txt}); ββ β
β 23 β } ββ β
β 24 β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββ<Variables>ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββ(unsigned char[36]) txt "The five boxing wizards jump quickly" ββ β
β ββ(elf.Elf64_Dyn) _DYNAMIC ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
β ββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Process: 24175 stopped Thread: 24175 Frame: 0 PC = 0x0000000001033c43
You can set breakpoints there by navigating to a line and pressing βbβ. To exit the GUI, press Esc.
The other commands can be found in the help.