Using the LLDB Debugger 使用LLDB调试器一步一步地运行Swift程序,通过设置断点调试运行状态。

  1. 创建一个名Factorial.swift,定义了一个factorial(n:)函数,并打印调用该函数的结果:
1
2
3
4
5
6
7
func factorial(n: Int) -> Int {
    if n <= 1 { return n }
    return n * factorial(n: n - 1)
}

let number = 4
print("\(number)! is equal to \(factorial(n: number))")
  1. swiftc命令 运行swiftc命令-g选项生成swift调试信息,在目录中生存可执行的Factorial文件:
1
2
3
4
5
$ swiftc -g Factorial.swift
$ ls
Factorial.dSYM
Factorial.swift
Factorial*
  1. 使用lldb启动Factorial文件 通过LLDB调试器命令lldb运行:
1
2
3
$ lldb Factorial
(lldb) target create "Factorial"
Current executable set to 'Factorial' (x86_64).
  1. 设置断点 使用breakpoint set (b) 命令在factorial(n:)函数的第2行中设置一个断点,每次执行函数时中断进程:
1
2
(lldb) b 2
Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12
  1. 运行调试 使用run (r)命令运行进程。进程在factorial(n:)函数的调用位置停止。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
(lldb) r
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14dfdf, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n: n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(n: number))")

Use the print (p) command to inspect the value of the n parameter.

1
2
(lldb) p n
(Int) $R0 = 4

The print command can evaluate Swift expressions as well.

1
2
(lldb) p n * n
(Int) $R1 = 16

Use the backtrace (bt) command to show the frames leading to factorial(n:) being called.

1
2
3
4
5
6
(lldb) bt
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    * frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
    frame #1: 0x0000000100000daf Factorial`main + 287 at Factorial.swift:7
    frame #2: 0x00007fff890be5ad libdyld.dylib`start + 1
    frame #3: 0x00007fff890be5ad libdyld.dylib`start + 1

Use the continue (c) command to resume the process until the breakpoint is hit again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
(lldb) c
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n: n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(n: number))")

Use the print (p) command again to inspect the value of the n parameter for the second call to factorial(n:).

1
2
(lldb) p n
(Int) $R2 = 3
  1. 取消断点 Use the breakpoint disable (br di) command to disable all breakpoints and the continue (c) command to have the process run until it exits.
1
2
3
4
5
6
(lldb) br di
All breakpoints disabled. (1 breakpoints)
(lldb) c
Process 40246 resuming
4! is equal to 24
Process 40246 exited with status = 0 (0x00000000)