디버거 사용

이 페이지에서는 OS 개발에 LLDB를 사용하는 방법을 자세히 설명합니다. 앱 개발의 경우 LLDB 기반의 Android 스튜디오 GUI를 사용하는 방법을 설명한 앱 디버그를 참고하세요.

GDB는 더 이상 지원되거나 제공되지 않습니다. GDB에서 LLDB로 전환한다면 LLDB 튜토리얼부터 읽어보는 것이 좋습니다. 전문 GDB 사용자라면 전환하는 동안 GDB에서 LLDB로의 명령어 지도가 매우 유용합니다.

기본 요건

디버거를 사용하려면 다음 단계를 따르세요.

  • 일반적인 envsetup.sh 명령어로 빌드 환경을 설정합니다.
  • 빌드할 때 사용한 것과 동일한 lunch 명령어를 실행합니다. lunch 항목은 디버깅하는 기기와 정확히 일치해야 합니다. lunch 항목이 연결된 기기와 일치하지 않으면 다음과 같은 오류 메시지가 표시됩니다. You used the wrong lunch: TARGET_PRODUCT (aosp_arm64) does not match attached device (xyzabc)
  • 기기를 시스템에 연결합니다.

환경 설정과 관련해 추가 도움이 필요한 경우 환경 설정을 참고하세요.

바이너리 디버그

시스템에서 빌드한 바이너리를 디버그하려면 먼저 기기에 바이너리를 복사하고 디버거를 실행해야 합니다. 예를 들면 다음과 같습니다.

adb push test.exe /data/local/tmp/test.exe
lldbclient.py --port 5038 -r /data/local/tmp/test.exe

실행 중인 앱 또는 프로세스 디버그

실행 중인 앱 또는 네이티브 데몬에 연결하려면 PID와 함께 lldbclient.py를 사용합니다. 예를 들어 PID 1234를 사용하여 프로세스를 디버그하려면 호스트에서 다음을 실행합니다.

lldbclient.py -p 1234

이 스크립트는 포트 전달을 설정하고 기기에서 적절한 원격 디버깅 스텁을 시작한 후, 호스트에서 디버거를 시작합니다. 그런 다음 기호를 찾도록 이 디버거를 구성한 후 원격 디버깅 스텁에 디버거를 연결합니다.

네이티브 프로세스 시작 디버깅

프로세스를 시작할 때 디버그하려면 -r 옵션과 함께 lldbclient.py를 사용합니다. 예를 들어 ls /bin을 디버그하려면 호스트에서 다음을 실행합니다.

lldbclient.py -r /system/bin/ls /bin

그런 다음 디버거 프롬프트에서 continue를 입력합니다.

앱 시작 디버그

앱이 시작될 때 앱을 디버깅하려는 경우가 있습니다. 예를 들어 충돌이 발생했고, 충돌 발생 무슨 문제가 있었는지 코드를 차근차근 살펴보고자 하는 경우가 여기에 해당합니다. 연결이 잘 작동하는 경우도 있지만, 연결하기 전에 앱이 충돌해 연결이 불가능한 경우도 있습니다. 앱에 포트를 열 수 있는 권한이 없을 수 있고 lldbserver가 이러한 제한사항을 상속받기 때문에 logwrapper 접근 방법(strace에 사용됨)이 항상 효과가 있는 것은 아닙니다.

앱 시작을 디버그하려면 설정의 개발자 옵션을 사용하여 Java 디버거가 연결될 때까지 앱이 대기하도록 지시합니다.

  1. 설정 > 개발자 옵션 > 디버그할 앱 선택으로 이동하고 목록에서 앱을 선택한 다음 디버거 연결 대기를 클릭합니다.
  2. 런처에서 또는 명령줄을 사용하여 실행하려는 앱을 시작합니다.
    adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
    
  3. 앱이 로드되고, 앱이 디버거를 대기하고 있음을 알리는 대화상자가 표시될 때까지 기다립니다.
  4. lldbserver/lldbclient를 일반적인 방법으로 연결하고 중단점을 설정한 다음 프로세스를 계속 진행합니다.

앱이 실행되도록 하려면 Java 디버거(jdb)와 같은 Java 디버그 유선 프로토콜(JDWP) 디버거를 연결합니다.

adb forward tcp:12345 jdwp:XXX  # (Where XXX is the PID
of the debugged process.)
jdb -attach localhost:12345

비정상 종료되는 앱 또는 프로세스 디버그

디버거에 연결할 수 있도록 debuggerd가 다운된 프로세스를 정지하도록 하려면 적절한 속성을 설정합니다.

  • Android 11 이상
    adb shell setprop debug.debuggerd.wait_for_debugger true
    
  • Android 11 이하
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow 이하
    adb shell setprop debug.db.uid 999999
    

일반적인 비정상 종료 출력 끝부분에서는 debuggerd가 logcat을 통해 디버거를 다운된 프로세스에 연결하는 방법을 보여주는 복사하여 붙여넣기 지침을 제공합니다.

VS Code로 디버그

LLDB는 Visual Studio Code에서 디버깅 플랫폼 코드를 지원합니다. LLDB CLI 인터페이스 대신 VS 코드 디버거 프런트엔드를 사용하여 기기에서 실행되는 네이티브 코드를 제어하고 디버그할 수 있습니다.

디버깅에 VS 코드를 사용하기 전에 CodeLLDB 확장 프로그램을 설치하세요.

VS 코드를 사용하여 코드를 디버그하는 방법:

  1. lldbclient.py를 실행하는 데 필요한 모든 빌드 아티팩트(예: 기호)가 있는지 또는 lldbclient.py가 있는지 확인합니다.
  2. VS Code에서 명령어를 실행할 수 있도록 Ctrl+Shift+P를 누르고 Debug: Add Configuration...을 검색한 다음 LLDB를 선택합니다. 그러면 launch.json 파일이 열리고 목록에 새 JSON 객체가 추가됩니다.
  3. 새로 추가된 디버거 구성을 주석 행 // #lldbclient-generated-begin// #lldbclient-generated-end로 대체합니다. 그러면 구성 목록이 다음과 같아집니다.
    "configurations": [
        // #lldbclient-generated-begin
        // #lldbclient-generated-end
    ]

    lldbclient.py는 이 주석을 사용하여 구성을 어디에 쓸지를 알아냅니다. 목록에 다른 항목이 있으면 다른 구성 뒤에 주석 행을 추가합니다.

  4. envsetup.shlunch를 실행한 터미널에서 다음 명령어를 실행합니다.
    lldbclient.py --setup-forwarding vscode-lldb \
          --vscode-launch-file LAUNCH_JSON_PATH \
          ANY_OTHER_FLAGS -p pid | -n proc-name | -r ...

    lldbclient.py가 생성된 구성을 launch.json에 쓴 다음 계속해서 실행됩니다. 이는 예상된 동작이므로 lldbclient.py 프로그램을 종료하지 마세요. --vscode-launch-file을 생략하면 스크립트가 JSON 스니펫을 출력합니다. 이 스니펫을 복사하여 launch.json에 수동으로 붙여넣어야 합니다.

    도구에서 플래그를 파싱하는 방식으로 인해 -r 플래그가 있다면 마지막 플래그여야 합니다.

  5. Run and Debug 사이드바를 엽니다. 디버거 목록에 새 구성이 나타납니다. Start Debugging (F5)을 누릅니다. 10~30초 후에 디버거가 연결됩니다.

    Run and Debug 보기에 새 구성이 나타나지 않는 경우, 창을 다시 로드하여 디버거 목록을 새로 고칩니다. Ctrl+Shift+P를 누르고 reload window를 입력하세요.

  6. 디버깅이 끝나면 lldbclient.py를 실행 중인 터미널로 이동하고 Enter를 눌러 lldbclient.py 프로그램을 종료합니다. 후속 스크립트 실행에서 #lldbclient-generated 주석 사이에 구성이 생성되어 기존 내용을 대체합니다. 따라서 기존 내용을 수동으로 삭제하지 않아도 됩니다.

생성된 실행 구성에 맞춤 속성을 추가하려면 --vscode-launch-props 플래그를 사용합니다. 예를 들면 다음과 같습니다.

lldbclient.py --setup-forwarding vscode-lldb \
    --vscode-launch-props \
    '{"initCommands" : ["script print(\"Hello\")"], "preLaunchTask" : "Build"}' \
    ...
예시 속성은 VS Code가 디버깅 전에 Build라는 작업을 실행하도록 하고 스크립트에 의해 생성된 단계에 새 디버그 초기화 단계를 추가합니다. 사용 가능한 속성의 개요는 VS Code 문서CodeLLDB 확장 프로그램 사용자 설명서에서 확인할 수 있습니다.