ndk-gdb

NDK에는 명령줄 네이티브 디버깅 세션을 시작하는 ndk-gdb 셸 스크립트가 포함되어 있습니다. GUI를 사용하고 싶은 사용자는 Android 스튜디오에서 디버깅 문서를 참조해야 합니다.

요구사항

명령줄 네이티브 디버깅이 작동하려면 다음 요구사항이 충족되어야 합니다.

  • ndk-build 스크립트를 사용하여 앱을 빌드합니다. ndk-gdb 스크립트는 레거시 make APP=<name> 메서드를 사용하여 빌드하는 기능을 지원하지 않습니다.
  • android:debuggable 속성을 true로 설정하는 <application> 요소를 포함하여 AndroidManifest.xml 파일에서 앱 디버깅을 사용 설정합니다.
  • Android 2.2(Android API 레벨 8) 이상에서 실행할 앱을 빌드합니다.
  • Android 2.2 이상을 실행하는 기기나 에뮬레이터에서 디버그합니다. AndroidManifest.xml 파일에서 선언하는 타겟 API 레벨은 디버깅에서 중요하지 않습니다.
  • Unix 셸에서 앱을 개발합니다. Windows에서는 Cygwin 또는 실험용 ndk-gdb-py Python 구현을 사용합니다.
  • GNU Make 3.81 이상을 사용합니다.

사용

ndk-gdb 스크립트를 호출하려면 애플리케이션 디렉터리 또는 그 아래의 디렉터리로 변경합니다. 예:

cd $PROJECT
$NDK/ndk-gdb

여기서 $PROJECT는 프로젝트의 루트 디렉터리를 가리키고 $NDK는 NDK 설치 경로를 가리킵니다.

ndk-gdb를 호출하면 생성되는 네이티브 라이브러리의 기호/디버그 버전과 소스 파일을 찾는 세션이 구성됩니다. 애플리케이션 프로세스에 성공적으로 연결되면 ndk-gdb가 다양한 시스템 라이브러리를 찾을 수 없다는 일련의 긴 오류 메시지를 출력합니다. 호스트 머신은 타겟 기기에 이러한 라이브러리의 기호/디버그 버전을 포함하지 않으므로 이러한 오류 메시지가 출력되는 것은 정상입니다. 따라서 이러한 메시지는 무시해도 됩니다.

다음으로, ndk-gdb는 일반 GDB 메시지를 표시합니다.

ndk-gdb와 상호작용하는 방식은 GNU GDB와 상호작용하는 방식과 같습니다. 예를 들어 b <location>을 사용하여 중단점을 설정하고 c('continue' 즉 계속)를 사용하여 실행을 재개할 수 있습니다. 전체 명령어 목록은 GDB 매뉴얼을 참조하세요.

GDB 메시지를 종료하면 디버깅 중인 애플리케이션 프로세스가 중지됩니다. 이 동작은 gdb 제한 사항입니다.

ndk-gdb는 여러 오류 조건을 처리하며 문제를 발견하면 정보용 오류 메시지를 표시합니다. 이러한 검사에는 다음과 같은 조건이 충족되는지 확인하는 작업이 포함됩니다.

  • ADB가 지정 경로에 있는지 확인합니다.
  • 애플리케이션이 해당 매니페스트에서 디버깅 가능한 것으로 선언되어 있는지 확인합니다.
  • 기기에서 같은 패키지 이름으로 설치되어 있는 애플리케이션 역시 디버깅이 가능한지 확인합니다.

기본적으로 ndk-gdb는 이미 실행 중인 애플리케이션 프로세스가 있는지 검색하고 실행 중인 프로세스를 찾지 못하는 경우 오류를 표시합니다. 하지만 --start 또는 --launch=<name> 옵션을 사용하여 디버깅 세션 전에 활동을 자동으로 시작할 수 있습니다. 자세한 내용은 옵션을 참조하세요.

옵션

전체 옵션 목록을 보려면 명령줄에 ndk-gdb --help를 입력하세요. 표 1에는 흔히 사용되는 여러 가지 옵션이 간략한 설명과 함께 나와 있습니다.

표 1. 일반적인 ndk-gdb 옵션과 설명

이 옵션을 지정하고 ndk-gdb를 시작하면 애플리케이션 manifest에 나열된 시작 가능한 첫 번째 활동이 시작됩니다. 그 다음으로 가능한 활동을 시작하려면 --launch=<name>을 사용하세요. 시작 가능한 활동 목록을 덤프하려면 명령줄에서 --launch-list를 실행합니다.

옵션 설명
--verbose

네이티브 디버깅 세션 설정에 관한 자세한 정보를 인쇄하도록 빌드 시스템에 지시하는 옵션입니다. 디버거가 앱에 연결할 수 없고 ndk-gdb가 표시하는 오류 메시지가 충분치 않을 경우에 대한 디버깅만을 위한 옵셥입니다.

--force 기본적으로 ndk-gdb는 다른 네이티브 디버깅 세션이 같은 기기에서 이미 실행 중인 것을 발견하면 취소됩니다. 이 옵션은 다른 세션을 중단하고 새 세션으로 바꿉니다. 이 옵션이 디버깅 중인 실제 앱을 중단하는 것은 아니므로, 따로 중단해야 합니다.
--start

ndk-gdb를 시작하면 기본적으로 타겟 기기에서 기존에 실행 중인 앱 인스턴스에 연결하려고 합니다. 디버깅 세션 전에 타겟 기기에서 애플리케이션을 명시적으로 시작하도록 --start를 사용하여 이 기본 동작을 재정의할 수 있습니다.

--launch=<name>

이 옵션은 애플리케이션에서 특정 활동을 시작할 수 있게 해준다는 점을 제외하면 --start와 유사합니다. 이 기능은 매니페스트에서 시작 가능한 여러 활동을 정의하는 경우에만 유용합니다.

--launch-list

앱 매니페스트에서 찾은 모든 시작 가능한 활동 이름 목록을 인쇄하는 편리한 옵션입니다. --start는 첫 번째 활동 이름을 사용합니다.

--project=<path> 앱 프로젝트 디렉터리를 지정하는 옵션입니다. 먼저 프로젝트 디렉터리로 변경할 필요 없이 스크립트를 시작하려고 할 때 유용합니다.
--port=<port>

기본적으로 ndk-gdb는 로컬 TCP 포트 5039를 사용하여 타겟 기기에서 디버깅 중인 앱과 통신합니다. 다른 포트를 사용하면 같은 호스트 머신에 연결되어 있는 다른 기기나 에뮬레이터에서 실행 중인 프로그램을 기본적으로 디버깅할 수 있습니다.

--adb=<file>

adb 도구 실행 파일을 지정하는 옵션입니다. 실행 파일을 포함할 경로를 설정하지 않은 경우에만 필요합니다.

  • -d
  • -e
  • -s <serial>
  • 이러한 플래그는 같은 이름을 가진 adb 명령과 유사합니다. 호스트 머신에 연결되어 있는 기기나 에뮬레이터가 여러 개인 경우 이러한 플래그를 설정합니다. 그 의미는 다음과 같습니다.

    -d
    단일 물리적 기기에 연결합니다.
    -e
    단일 에뮬레이터 기기에 연결합니다.
    -s <serial>
    특정 기기나 에뮬레이터에 연결합니다. 여기서 <serial>adb devices 명령어를 사용하면 나열되는 기기의 이름입니다.

    또는 특정 옵션을 사용할 필요 없이 특정 기기를 나열하도록 ADB_SERIAL 환경 변수를 정의할 수 있습니다.

  • --exec=<file>
  • -x <file>
  • 디버깅 중인 프로세스에 연결한 후 <file>에 있는 GDB 초기화 명령어를 실행하도록 ndk-gdb에 지시하는 옵션입니다. 중단점 목록을 설정한 후 자동으로 실행을 계속할 때와 같이 어떤 작업을 반복적으로 하고 싶을 때 유용한 기능입니다.

    --nowait

    GDB가 연결할 때까지 Java 코드 일시중지를 비활성화합니다. 이 옵션을 설정하지 않으면 디버거에서 조기 중단점이 누락될 수 있습니다.

    --tui -t

    텍스트 사용자 인터페이스가 지원된다면 이를 사용 설정합니다.

    --gnumake-flag=<flag>

    프로젝트 정보를 쿼리할 때 ndk-build 시스템에 전달할 추가 플래그를 하나 이상 지정하는 데 사용되는 옵션입니다. 같은 명령어에 이 옵션의 인스턴스를 여러 개 사용할 수 있습니다.

    참고: 이 표의 마지막 3개 옵션은 Python 버전의 ndk-gdb에만 적용됩니다.

    스레드 지원

    앱이 Android 2.3(API 레벨 9) 이전 버전의 플랫폼에서 실행되는 경우 ndk-gdb가 네이티브 스레드를 제대로 디버깅할 수 없습니다. 디버거는 기본 스레드만 디버깅할 수 있으며 abd는 다른 스레드의 실행을 완전히 무시합니다.

    기본 스레드 이외의 스레드에서 실행되는 함수에 중단점을 배치하면 프로그램이 종료되고 GDB가 다음 메시지를 표시합니다.

    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
          The program no longer exists.