Featured image of post LLDB(Low-Level-Debugger)

LLDB(Low-Level-Debugger)

LLVM(Low-Level-Virtual-Machine)

LLDB가 무엇인지 공부하기 위해서, 먼저 LLVM이 무엇인지 알아보자.

위키에서는

프로그램을 컴파일 타임, 링크 타임, 런타임 상황에서 프로그램의 작성 언어에 상관없이 최적화를 쉽게 구현할 수 있도록 구성되어 있는 컴파일러 기반 구조

라고 설명하고 있다.

LLDB는 LLVM 프로젝트를 통해 개발된 모듈을 디버깅하는 디버거로써 C, C++, Objective-C, Swift를 지원하고 현재는 Xcode에 내장되어 있는 기본 디버거이다.

XCode에서는 실행중인 프로세스가 breakpoint에서 멈추거나, pause 버튼을 눌러서 실행이 멈추면(단축키: command + control + y) 하단 Debug Area에 LLDB 콘솔이 노출된다.

LLDB 기본 문법

1
(lldb) command [subcommand] -option "this is argument"

command, subcommand, option, argument로 구성되어 있고 띄어쓰기로 구분한다.

  • command, subcommand : LLDB내의 Object 이름(ex. breakpoint, watchpoint, set, list 등)
  • option : 명령어에 따른 옵션 하이픈(-)으로 시작한다.
  • argument : 명령어에 따른 인자, 공백이 포함될 수도 있기 때문에 큰따옴표(" “)로 감싸 주어야 한다.
1
(lldb) breakpoint set --file test.c --line "12"

위 명령어는 test.c 라는 파일의 12번째 라인에 breakpoint를 설정(set)하는 명령어이다.

Help

사용 가능한 subcommand나 option을 확인하고 싶을 때는 help 명령어를 사용하면 좋다.

1
(lldb) help

⬆️ LLDB에서 제공하는 Command 목록을 확인할 수 있다.

1
(lldb) help breakpoint

⬆️ breakpoint의 subcommand 에 대한 명령어를 확인할 수 있다.

1
(lldb) help breakpoint set

⬆️ breakpoint set 의 Option을 확인할 수 있다.

Apropos

원하는 기능의 명력어가 있는지 확인하고 싶을 때는 apropos 명령어를 사용할 수 있다.

1
2
3
4
5
# referent count를 체크할 수 있는 명령어가 있을지 확인하고 싶을 때
(lldb) apropos "refernce count"

# The following commands may relate to 'reference count':
#    refcount -- Inspect the reference count data for a Swift object

Breakpoint

디버깅 시 중단점(breakpoint)을 설정하면 해당 위치에서 프로그램의 실행을 멈출 수 있다.

1
2
3
(lldb) breakpoint set [option] "arguments"
# 맨 앞 알파벳만 입력해도 명령어를 실행할 수 있다. same as above
(lldb) br s [option] "arguments"

Function name

특정 이름을 가진 모든 함수에 -name 옵션을 사용하여 breakpoint를 설정할 수 있다.

1
2
3
# viewDidLoad 함수에 breakpoint를 설정
  (lldb) breakpoint set --name viewDidLoad
  (lldb) b -n viewDidLoad

File name

파일 이름과 line number를 이용하여 breakpoint를 설정할 수 있다.

1
2
3
# ViewController.swift 파일의 12번째 라인에 breakpoint를 설정
  (lldb) breakpoint set --file ViewController.swift --line 12
  (lldb) b s -f ViewController.swift -l 12

Condition

조건을 설정하여 breakpoint를 설정할 수 있다.

1
2
3
4
5
6
7
# viewWillAppear 호출시, animated가 true인 경우에만 break
  (lldb) breakpoint set --name "viewWillAppear" --condition animated
  (lldb) br s -n "viewWillAppear" -c animated

# ViewControler.swift 파일의 17번째 라인에서 helloWorld가 "abc"인 경우 break
  (lldb) breakpoint set --file ViewController.swift --line 17 --condition helloWorld == "abc"
  (lldb) br s -f ViewController.swift -l 17 -c helloWorld == "abc"

break list

breakpoint list 명령으로 현재 설정된 breakpoint를 확인할 수 있다.

1
2
3
4
5
6
7
# breakpoint 목록 전체 출력
  (lldb) breakpoint list
  (lldb) br list
# breakpoint 목록 간단하게 출력 (brief)
  (lldb) br list -b
# 특정 id를 가진 breakpoint의 정보만 출력
  (lldb) br list 1

break delete / disable

breakpoint delete 명령으로 설정된 breakpoint를 삭제할 수 있고, breakpoint disable 명령으로 설정된 breakpoint를 비활성화할 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# breakpoint 전체 삭제
  (lldb) breakpoint delete
  (lldb) br de
# 특정 breakpoint 삭제
  (lldb) br de 1
# breakpoint 전체 비할성화
  (lldb) breakpoint disable
  (lldb) br di
# 특정 breakpoint 비활성화
  (lldb) br di 1

Stepping

break되어 있는 상태에서 프로그램의 실행을 한 단계씩 진행시키면서 상태 변화를 관찰할 수 있다.

stepping over

next 명령어를 사용하여 다음 라인으로 진행시킬 수 있다.

1
2
(lldb) next
(lldb) n

stepping in

step 명령어를 사용하여 다음 statement가 함수인경우 함수 내부의 시작시점으로 진행시킬 수 있다. next명령을 사용했다면 함수를 만나도 다음 statement로 진행시킨다는 점이 다르다.

1
2
(lldb) step
(lldb) s

stepping out

finish 명령어를 사용하여면 현재 함수가 return될 때까지 진행하고 break된다.

1
2
(lldb) finish
(lldb) f

Expression

po

객체의 값을 출력할 수 있다.

1
2
(lldb) po helloWorld
(lldb) p helloWorld

expression

expression 명령어를 사용하여 정보를 출력하고 값을 변경해서 다시 출력할 수도 있다.

LLDB에서는 내부적으로 값이 출력되면 $R- 형태로 저장되고, 이 값을 다시 사용할 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# view의 정보를 출력
(lldb) expression self.view

# $R0이라는 변수에 view의 정보가 저장됨
# $R0의 백그라운드 컬러를 파란색으로 변경
(lldb) expression $R0.backgroundColor = UIColor.blue

# Code를 계속 진행
(lldb) continue

# view 파란색으로 바뀌어 보여짐

변수를 직접 선언해서 사용할 수도 있다. 이때는 사용하려는 변수명 앞에 $를 붙여줘야 한다.

1
2
(lldb) expr let $testNumber = 1
(lldb) expr var $testString = "test"

--ignore-breakpoints 옵션을 사용하면 breakpoint를 무시하고 코드를 계속 진행시킬 수 있다.

1
(lldb) expr --ignore-breakpoints

Reference

야곰닷넷 - LLDB 정복
Understanding Xcode Build System
wiki - LLVM