[lldb] breakpoint 의 command 옵션과 expression을 이용한 라이브 디버깅

세상 사람들 또 나만 빼고 편하게 디버깅 중이었지???? 어??!?!

naljin
7 min readSep 5, 2021

저는 요 며칠 lldb 공부 중이에요. 뭔 컨퍼런스인진 기억안나지만 이전에 lldb 세션 듣고서 우왕 공부해야지 ㅇ0ㅇ!! 했던 기억은 있는데 ㅎㅎ,, 그러고서 몇년 후에 공부하는 내가 ㄹㅈㄷ ㅜ 공부 안하니 응??????????? 뭐 거기서 스티커랑 굿즈나 얻고 왔겠죠 ㅎㅎㅎㅎㅎㅎㅎ,,,◠‿◠

거기서 얻은건,, 과연 무엇?

튼 이것 저것 보고 있는디 [WWDC 2018] Advanced Debugging with Xcode and LLDB 영상 보다가 진짜 개쩌는 기능이 있는거예요?! 이건 포스팅 안하고 못참지;; 하 2018 년 영상이니까,, 나만 3년 손해 보고 있었음 또;;

문제 상황

🤔 아래 코드에서 텍스트 뷰 클릭해도 print 되지 않는데,, 흠 머가 문젤까

class SecondViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
}

func textViewDidBeginEditing(_ textView: UITextView) {
print(textView.text)
}
}

😞 아앗,, tableView.delegate = self 코드를 추가 안해서 에러난거 같군. 하,, 확인하려면 코드 추가한 다음에 재빌드해야하는데 빌드 시간 백만년 걸리네 (이마짚)

해결 방법

🤓 이럴 땐 브레이크 포인트를 이용해보세요!

🤔 에? 브포요? 여기서요?

🤓 브레이크 포인트에서 변경 사항을 주입하는 방식으로 바로 라이브로 테스트할 수 있답니당!

예를 들어 위의 SecondViewControllerRootViewController 에서 push 되는 애라고 해볼게요. RootViewController에서 SecondViewController 로 push 될 때 viewDidLoad 가 실행 되겠죠? 이렇게 특정 코드가 실행 될 수 있는 곳에 브레이크 포인트를 찍어줍니다

브레이크 포인트를 더블 클릭을 하면 편집할 수 있는 창이 뜨는데요, 여기서 Action 버튼을 누르면 lldb 명령어를 입력할 수 있는 필드가 생깁니다.

제가 원하는건 delegate를 설정하는거니까 expression textView.delegate = self 명령어를 써줬습니다. 이게 의미하는 바는 좀 이따 보도록 할게요. 참고로 밑에 Automatically continue after evaluating actions 를 체크한건 breakpoint가 트리거 되어도 거기서 일시 중단되지 않고 프로그램을 계속 진행하게 하기 위함이에요!

이제 RootViewController로 갔다가 SecondViewController에 다시 들어와 viewDidLoad 쪽에 걸린 브레이크 포인트를 트리거 시켜주면? 굳이 재빌드 하지 않고도 textViewdelegate 를 설정한 후에 이게 정말 문제의 해결책이 맞나 빠르게 확인 할 수 있게 되는거죠. ㅁㅊㄷ ㅁㅊㅇ;;;;

Evaluating Expression

그럼 위에서 입력한 expression textView.delegate = self 이 뭔지 좀 더 살펴봅시다.

expression (expr, ex, e) 은 lldb 의 명령어 중 하나입니다. lldb 의 명령어로는 expression 말고도 breakpoint , thread , frame image 등으로 다양해요! 알고 있는 명령어가 많을 수록 사용할 수 있는 기능이 많아지겠죠?

이렇게 다양한 명령어 중에서 expression 은 가장 유용하고 강력한 명령 중 하나로, 이를 통해 코드를 실행할 수 있을 뿐만 아니라 프로젝트를 다시 컴파일하지 않고도 기존 변수를 수정할 수도 있습니다.

딜리게이트 설정 말고도 expression textView.text = "naljin" 처럼 기존 변수를 수정할 수도 있답니다.

참고로 lldb 를 잘 몰라도 (lldb) po self 처럼 po 명령어까지 쓰시는 분들은 많을 것 같은데요! 이는 expression --object-description -- 의 약자로, 알고보면 po도 expression 명령어였다는 사실! 여기서 --object-description (-O) 은 object의 설명(debugDescription)을 출력하겠다는 의미를 가지는 expression 명령어의 option 이에요.

Set breakpoint using lldb

방금 저희는 브레이크 포인트를 UI 에서 설정했지만 콘솔에서 lldb 명령어로 설정할 수도 있어요.

# 긴 버전
(lldb) breakpoint set --line 70 --command "expression textView.delegate = self" --auto-continue 1
# 짧 버전
(lldb) br s -l 70 -C "e textView.delegate = self" -G1

하나씩 쪼개서 보자면,

  • breakpoint set : 브레이크 포인트를 걸겠다 (짧: br s)
  • --line 70 : 70번째 라인에 (짧 : -l 70)
  • --command "~~" : breakpoint 걸릴 때 "~~"라는 lldb 명령어를 추가로 실행하겠다 (짧 : -C "~~" . 참고로 -c-condition의 짧버전.)
  • --auto-continue 1 : command 실행 후 break에 걸린채로 있지 않고 프로그램을 자동 진행하게 해줌 (짧 : -G1). 여기서 1true의 의미로 --auto-continue true 해도 됨. -G0--auto-continue false 의 의미.

마무리

내용 중 이 부분이 가장 충격적이어서 요 부분만 떼어다 가져왔지만 해당 WWDC 세션은 꼭 보시는걸 추천 드려요!

추가로 lldb 에 대해 공부해보고 싶으신 분들은 아래 튜토리얼을 추천드림다

추가로 ㅈㅓ 내용들을 따라 해보면서 나름대로 정리해본 나만의 정리본도 살짜쿵 놓고감..

https://github.com/sujinnaljin/Improving_Productivity

그럼 20000~!

출처

--

--