[Day 41] 안녕 print(), 반가워 LLDB! | Xcode 디버깅 첫걸음
고백합니다. 저의 디버깅 친구는 오직 print()였습니다. 이제 Xcode의 숨겨진 보석, LLDB를 만나 디버깅의 신세계를 경험한 후기를 공유합니다.
😭 print()
와 작별할 시간
고백하자면, 지금까지 나의 디버깅 친구는 오직 print()
였다.
변수 값이 궁금하면 print()
, 객체 상태가 궁금해도 print()
.
코드는 금세 print()
로 도배되었고, 정작 원하는 정보를 찾으려면 콘솔 창에서 눈을 부릅떠야 했다. 디버깅이 끝나면 이 모든 print()
를 지우는 건 또 다른 일이었다.
오늘, 드디어 이 비효율의 굴레에서 벗어나게 해 줄 Xcode의 숨겨진 보석, LLDB를 만났다.
✨ LLDB: Xcode에 내장된 디버깅 슈퍼파워
LLDB(Low Level Debugger)는 Xcode에 기본으로 탑재된 전문 디버거다.
우리가 코드에 중단점(Breakpoint)을 걸면, 앱 실행이 그 지점에서 멈추고 디버그 콘솔이 우리를 맞이한다. 바로 그 콘솔이 LLDB와 대화하는 창구다.
print()
와 LLDB의 가장 큰 차이점은 ‘실시간 소통’이 가능하다는 점이다. 코드를 고치고, 다시 빌드하고, 결과를 기다리는 과정 없이, 멈춰진 앱의 상태를 실시간으로 묻고, 확인하고, 심지어 조작까지 할 수 있다.
🚀 오늘 정복한 LLDB 핵심 명령어 TOP 3
LLDB의 모든 것을 하루 만에 알 수는 없지만, 이것 세 개만 알아도 디버깅 생산성이 폭발적으로 증가할 것 같다.
아래와 같은 User
객체가 있다고 상상하고 살펴보자.
1
2
3
4
5
6
7
struct User {
let id: Int
var name: String
var isActive: Bool
}
let currentUser = User(id: 1, name: "오류낸 춘식이", isActive: true)
1. po
(Print Object): “이거 뭐야? 예쁘게 보여줘”
객체의 내용을 사람이 읽기 좋은 형태로 보여준다. 객체의 description
정보를 요약해서 보여준다고 생각하면 편하다. 앞으로 가장 많이 쓰게 될 단짝 같은 명령어다.
(lldb) po currentUser
▿ User
- id: 1
- name: "오류낸 춘식이"
- isActive: true
2. p
(Print): “더 자세히, 날것 그대로 보여줘”
po
보다 더 기술적이고 상세한 정보를 보여준다. 변수의 정확한 타입이나 메모리 주소 같은 내부 구조가 궁금할 때 유용하다.
(lldb) p currentUser
(ChunsikBook.User) $R0 = (id = 1, name = "오류낸 춘식이", isActive = true)
3. expression
(단축키 e
): “값을 바꿔보자!”
오늘의 하이라이트. 단순히 값을 보는 것을 넘어, 실행 중에 변수의 값을 마음대로 바꿀 수 있다. “만약 이 값이 false
라면?” 같은 가정을 테스트하기 위해 더 이상 코드를 수정하고 앱을 다시 켤 필요가 없다.
// 1. 현재 isActive 값 확인
(lldb) po currentUser.isActive
true
// 2. expression 명령어로 값을 변경!
(lldb) expression currentUser.isActive = false
// 3. 다시 확인해보면...
(lldb) po currentUser.isActive
false
맺으며: 춘식이의 다짐
오늘은 LLDB의 문을 살짝 열어본 것뿐이지만, 왜 선배 개발자들이 print()
대신 디버거 사용을 강조했는지 뼈저리게 느꼈다. 아직은 명령어를 치는 손이 어색하지만, 의식적으로 LLDB와 친해지려 노력해야겠다. 스마트한 디버깅이 스마트한 개발자를 만드는 첫걸음일 테니까.
혹시 이 글을 보시는 분들 중 더 유용한 LLDB 팁이 있다면 댓글로 많이 알려주세요!