Published on

๐ŸŽ Swift - LLDB

Authors
  • avatar
    Name
    ์ด์ฐฝ์ค€
    Twitter

LLDB (Low-Level-Debugger)

LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the largerย LLVM Project, such as the Clang expression parser and LLVM disassembler.

LLDB๋Š” LLVM(Low-Level-Virtual-Machine)์˜ ์„œ๋ธŒ ํ”„๋กœ์ ํŠธ๋“ค ์ค‘ ํ•˜๋‚˜๋กœ์„œ, ๋ง ๊ทธ๋Œ€๋กœ ๋””๋ฒ„๊ฑฐ์ž…๋‹ˆ๋‹ค. LLVM ํ”„๋กœ์ ํŠธ๋Š” ํฌ๋ฆฌ์Šค ๋ž˜ํŠธ๋„ˆ์— ์˜ํ•ด ์‹œ์ž‘๋˜์—ˆ๊ณ , ์ดํ›„ ์• ํ”Œ์— ์˜์ž…๋˜์–ด ํ˜„์žฌ๋Š” Xcode์˜ ๊ธฐ๋ณธ ๋””๋ฒ„๊ฑฐ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

LLDB ์‚ฌ์šฉํ•˜๊ธฐ

LLDB๋Š” Xcode์˜ ํ•˜๋‹จ์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ผ์‹œ ์ •์ง€๋˜๊ฑฐ๋‚˜ breakpoint์— ๊ฑธ๋ ธ์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํ™”๋ฉด ๋งŽ์ด ๋ณด์…จ์ฃ ?

์ €๋Š” LLDB๋ฅผ ๋ชจ๋ฅผ ๋•Œ 11๋ฐ์‹œ๋ฒจ ๋ญ ์ด๋Ÿฐ๊ฑด๊ฐ€..? ํ–ˆ๋Š”๋ฐ lldb๋ผ๋Š” ๋””๋ฒ„๊ฑฐ๋ผ๋Š” ๋œป์ด์˜€์–ด์š”.. ๐Ÿ˜…

(lldb) <noun> <verb> [-options [option-value]] [argument [argument...]]

LLDB์˜ ๋ช…๋ น์–ด๋Š” ์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

<noun>๊ณผ <verb>์—๋Š” command์™€ subcommand๊ฐ€ ์˜ต๋‹ˆ๋‹ค. (breakpoint, set, list ๊ฐ™์€...)

option์€ ๋‹ค๋ฅธ cli ํˆด๊ณผ ๋น„์Šทํ•˜๊ฒŒ -f ํ˜น์€ --file๊ฐ™์ด -๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์‚ดํŽด๋ด…์‹œ๋‹ค.

(lldb) breakpoint set --file foo.c --line 12
(lldb) breakpoint set -f foo.c -l 12

breakpoint๋ผ๋Š” ๋ช…๋ น์–ด์˜ ํ•˜์œ„ ๋ช…๋ น์–ด set์ด ์‹คํ–‰๋˜๊ณ  ์žˆ๋„ค์š”. --file ์˜ต์…˜์„ ํ†ตํ•ด foo.c ํŒŒ์ผ์„ ์ง€์ •ํ•ด์ฃผ๊ณ , --line ์˜ต์…˜์„ ํ†ตํ•ด 12๋ฒˆ ๋ผ์ธ์„ ์ง€์ •ํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

help์™€ apropos

๋‹น์—ฐํ•˜๊ฒŒ๋„ ๋ชจ๋“  ์ปค๋งจ๋“œ๋ฅผ ๋‹ค ์™ธ์šธ์ˆ˜๋Š” ์—†๊ฒ ์ฃ ? man๊ณผ ๊ฐ™์€ ๋„์›€๋ง ์ปค๋งจ๋“œ๊ฐ€ LLDB์—๋„ ๋‹น์—ฐํ•˜๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ help์™€ ์ปค๋งจ๋“œ, ํ˜น์€ ์„œ๋ธŒ์ปค๋งจ๋“œ์˜ ๋„์›€๋ง์„ ๋ณผ ์ˆ˜ ์žˆ๊ตฌ์š”..

apropos๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฃผ์–ด์ง„ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ด€๋ จ๋œ ์ปค๋งจ๋“œ๋“ค์„ ์•ˆ๋‚ดํ•ด์ค๋‹ˆ๋‹ค.

Breakpoint

์œ„์—์„œ ์ž ๊น ๋ง›๋ณธ ๊ฒƒ ์ฒ˜๋Ÿผ LLDB๋ฅผ ์‚ฌ์šฉํ•ด breakpoint๋ฅผ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”, ์ด ๋ถ€๋ถ„์€ ์‚ฌ์‹ค Xcode์—์„œ GUI ํ™˜๊ฒฝ์œผ๋กœ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ดํŽด๋ณด๊ณ  ๋„˜์–ด๊ฐ‘์‹œ๋‹ค.

Breakpoint ๋งŒ๋“ค๊ธฐ

์ผ๋‹จ breakpoint๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋งŒ๋“ค์–ด์•ผ๊ฒ ์ฃ ?

  • Function Name
    (lldb) breakpoint set --name viewDidLoad
    
  • File
    (lldb) breakpoint set --file ViewController.swift --line 20
    
  • Condition
    (lldb) breakpoint set --name "viewWillAppear" --condition animated
    

ํ•จ์ˆ˜์˜ ์ด๋ฆ„, ํŒŒ์ผ, ํ˜น์€ ์กฐ๊ฑด์„ ์ฃผ์–ด์„œ breakpoint๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. Xcode์—์„œ ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒƒ ๊ฐ™๋‹ค๊ตฌ์š”? ๋งž์•„์š”.. Xcode์˜ breakpoint ๊ธฐ๋Šฅ๋„ LLDB๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋“ ์š”. ๊ทธ๋ž˜์„œ ์‚ฌ์‹ค ๊ทธ๊ฒŒ ๊ทธ๊ฑฐ๋ž๋‹ˆ๋‹ค ๐Ÿ˜Š

Breakpoint ๋ฆฌ์ŠคํŠธ ํ™•์ธํ•˜๊ธฐ

(lldb) breakpoint list

์ด๋ ‡๊ฒŒ ํ˜„์žฌ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š” breakpoint๋“ค์˜ ๋ชฉ๋ก๋„ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Breakpoint ์‚ญ์ œ/๋น„ํ™œ์„ฑํ™”ํ•˜๊ธฐ

(lldb) breakpoint delete (breakpoint id)
(lldb) breakpoint disable (breakpoint id)

๋น„ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ๋„ ๋‹น์—ฐํžˆ ์žˆ์–ด์•ผ๊ฒ ์ฃ . ๋ช…๋ น์–ด์˜ ๋’ค์— breakpoint์˜ id๋ฅผ ์ฃผ๋ฉด ํŠน์ • breakpoint์— ๋Œ€ํ•ด์„œ๋งŒ ์ˆ˜ํ–‰๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Stepping

breakpoint๋ฅผ ๊ฑธ์—ˆ๋‹ค๋ฉด, ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ธฐ๋Šฅ๋„ ์žˆ์„๊ฒ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ด ๊ธฐ๋Šฅ๋„ ํ„ฐ๋ฏธ๋„์˜ ์ƒ๋‹จ์— ๋ฒ„ํŠผ์œผ๋กœ ์‰ฝ๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ดํŽด๋ด…์‹œ๋‹ค.

  • Stepping Over
    (lldb) next
    
    breakpoint๊ฐ€ ๊ฑธ๋ฆฐ ์ง€์ ์˜ ๋ฐ”๋กœ ๋‹ค์Œ statement๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • Stepping In
    (lldb) step
    
    breakpoint๊ฐ€ ๊ฑธ๋ฆฐ ์ง€์  ๋‹ค์Œ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด, ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์‹œ์ž‘ ์ง€์ ์œผ๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • Stepping Out
    (lldb) finish
    
    ํ˜„์žฌ ํ•จ์ˆ˜๋ฅผ ๋๋‚ด๊ณ  ๊ทธ ์ดํ›„์˜ statement์— breakpoint๋ฅผ ๊ฑธ์–ด์ค๋‹ˆ๋‹ค.

Expression

breakpoint๋กœ ์ธํ•ด ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉˆ์ถฐ ์žˆ์„ ๋•Œ LLDB๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ์—ˆ์ฃ ? ์ด ๋•Œ์˜ ์ƒํ™ฉ์—์„œ expression ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ ํŠน๋ณ„ํ•œ ๋™์ž‘๋“ค์„ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ด ๋ถ€๋ถ„ ๋•Œ๋ฌธ์— LLDB์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ๋งˆ์Œ์ด ์ƒ๊ฒผ๋‹ต๋‹ˆ๋‹ค ๐Ÿ˜Š

po

๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋  ๋ช…๋ น์–ด (lldb) po์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ !

์ฐธ๊ณ ๋กœ po๋Š” print -O --์˜ alias์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ธ์Šคํ„ด์Šค์˜ ์ •๋ณด๋ฅผ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

class Test: NSObject {
ย  ย  var a = 1

ย  ย  override var debugDescription: String {
ย  ย  ย  ย  return "Test Instance!!"
ย  ย  }
}

์ฐธ๊ณ ๋กœ ์ด ๋•Œ ์ถœ๋ ฅ๋˜๋Š” ๊ฐ’์€ NSObject์˜ debugDescription ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ overrideํ•ด์ฃผ๋ฉด ์ปค์Šคํ…€ ๋œ ์ถœ๋ ฅ๊ฐ’์„ ์–ป์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

variable ์‚ฌ์šฉํ•˜๊ธฐ

(lldb) e (variable)

์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น variable์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ณ , ์ฃผ์–ด์ง€๋Š” $R0์™€ ๊ฐ™์€ ๋ณ€์ˆ˜๋กœ ์ ‘๊ทผํ• ์ˆ˜๋„ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

(lldb) e $R0.a = 2

๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํ•ด๋‹น ๋ณ€์ˆ˜์˜ a ๊ฐ’์„ 2๋กœ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋‹ค์‹œ ํ•œ ๋ฒˆ e test๋ฅผ ํ†ตํ•ด์„œ ์ •๋ณด๋ฅผ ์กฐํšŒํ•ด๋ณด๋‹ˆ a์˜ ๊ฐ’์ด 2๊ฐ€ ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ์ด๋ฏธ ์žˆ๋Š” ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค!

(lldb) e let $someNumber = 10
(lldb) e var $someString = "Hello, World!"

์ถœ์ฒ˜ Tutorial - ๐Ÿ› LLDB ์•ผ๊ณฐ๋‹ท๋„ท - LLDB ์ •๋ณต