I’m hacking on an assembly project, and wanted to document some of the tricks I
was using for figuring out what was going on. This post might seem a little
basic for folks who spend all day heads down in gdb or who do this stuff
professionally, but I just wanted to share a quick intro to some tools that
others may find useful.
(oh god, I’m doing it)
If your coming from gdb to lldb, there’s a few differences in commands. LLDB
has
great documentation
on some of the differences. Everything in this post about LLDB is pretty much
there.
The bread and butter commands when working with gdb or lldb are:
r (run the program)
s (step in)
n (step over)
finish (step out)
c (continue)
q (quit the program)
You can hit enter if you want to run the last command again, which is really
useful if you want to keep stepping over statements repeatedly.
I’ve been using LLDB on OSX. Let’s say I want to debug a program I can build,
but is crashing or something:
1
$ sudo lldb ./asmttpd web_root
Setting a breakpoint on jump to label:
12
(lldb) b sys_write
Breakpoint 3: where= asmttpd`sys_write, address= 0x00000000000029ae
When you’re trying to figure out what system calls are made by some C code,
using dtruss is very helpful. dtruss is available on OSX and seems to be some
kind of wrapper around DTrace.
If you compile with -g to emit debug symbols, you can use lldb’s disassemble
command to get the equivalent assembly:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ clang sleep.c -g
$ lldb a.out
(lldb) target create "a.out"
Current executable set to 'a.out'(x86_64).
(lldb) b main
Breakpoint 1: where= a.out`main + 16 at sleep.c:3, address= 0x0000000100000f40
(lldb) r
Process 33213 launched: '/Users/Nicholas/code/assembly/asmttpd/a.out'(x86_64)
Process 33213 stopped
* thread #1: tid = 0xeca04, 0x0000000100000f40 a.out`main + 16 at sleep.c:3, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f40 a.out`main + 16 at sleep.c:3
1 #include <time.h>
2 int main (){
-> 3 struct timespec rqtp={
4 2,
5 0
6 };
7
(lldb) disassemble
a.out`main:
0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq $0x20, %rsp
0x100000f38 <+8>: leaq -0x10(%rbp), %rdi
0x100000f3c <+12>: xorl %eax, %eax
0x100000f3e <+14>: movl %eax, %esi
-> 0x100000f40 <+16>: movq 0x49(%rip), %rcx
0x100000f47 <+23>: movq %rcx, -0x10(%rbp)
0x100000f4b <+27>: movq 0x46(%rip), %rcx
0x100000f52 <+34>: movq %rcx, -0x8(%rbp)
0x100000f56 <+38>: callq 0x100000f68 ; symbol stub for: nanosleep
0x100000f5b <+43>: xorl %edx, %edx
0x100000f5d <+45>: movl %eax, -0x14(%rbp)
0x100000f60 <+48>: movl %edx, %eax
0x100000f62 <+50>: addq $0x20, %rsp
0x100000f66 <+54>: popq %rbp
0x100000f67 <+55>: retq
Anyways, I’ve been learning some interesting things about OSX that I’ll be
sharing soon. If you’d like to learn more about x86-64 assembly programming,
you should read my other posts about
writing x86-64
and a toy
JIT for Brainfuck
(the creator of Brainfuck liked it).
I should also do a post on
Mozilla’s rr,
because it can do amazing things like step backwards. Another day…
No comments :
Post a Comment