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 매뉴얼을 참조하세요. LLDB 디버거를 사용하려면 ndk-gdb
스크립트를 호출할 때 --lldb
옵션을 사용합니다.
GDB 메시지를 종료하면 디버깅 중인 애플리케이션 프로세스가 중지됩니다. 이 동작은 gdb 제한 사항입니다.
ndk-gdb
는 여러 오류 조건을 처리하며 문제를 발견하면 정보용 오류 메시지를 표시합니다. 이러한 검사에는 다음과 같은 조건이 충족되는지 확인하는 작업이 포함됩니다.
- ADB가 지정 경로에 있는지 확인합니다.
- 애플리케이션이 해당 매니페스트에서 디버깅 가능한 것으로 선언되어 있는지 확인합니다.
- 기기에서 같은 패키지 이름으로 설치되어 있는 애플리케이션 역시 디버깅이 가능한지 확인합니다.
기본적으로 ndk-gdb
는 이미 실행 중인 애플리케이션 프로세스가 있는지 검색하고 실행 중인 프로세스를 찾지 못하는 경우 오류를 표시합니다. 하지만 --start
또는 --launch=<name>
옵션을 사용하여 디버깅 세션 전에 활동을 자동으로 시작할 수 있습니다. 자세한 내용은 옵션을 참조하세요.
옵션
전체 옵션 목록을 보려면 명령줄에 ndk-gdb --help
를 입력하세요. 표 1에는 흔히 사용되는 여러 가지 옵션이 간략한 설명과 함께 나와 있습니다.
이 옵션을 지정하고 ndk-gdb
를 시작하면 애플리케이션 manifest에 나열된 시작 가능한 첫 번째 활동이 시작됩니다. 그 다음으로 가능한 활동을 시작하려면 --launch=<name>
을 사용하세요. 시작 가능한 활동 목록을 덤프하려면 명령줄에서 --launch-list
를 실행합니다.
옵션 | 설명 |
---|---|
--lldb |
이 옵션을 설정하면 스크립트는 세션에 gdb 대신 LLDB 디버거를 사용합니다. |
--verbose |
네이티브 디버깅 세션 설정에 관한 자세한 정보를 인쇄하도록 빌드 시스템에 지시하는 옵션입니다. 디버거가 앱에 연결할 수 없고 |
--force |
기본적으로 ndk-gdb 는 다른 네이티브 디버깅 세션이 같은 기기에서 이미 실행 중인 것을 발견하면 취소됩니다. 이 옵션은 다른 세션을 중단하고 새 세션으로 바꿉니다.
이 옵션이 디버깅 중인 실제 앱을 중단하는 것은 아니므로, 따로 중단해야 합니다. |
--start |
|
--launch=<name> |
이 옵션은 애플리케이션에서 특정 활동을 시작할 수 있게 해준다는 점을 제외하면 |
--launch-list |
앱 매니페스트에서 찾은 모든 시작 가능한 활동 이름 목록을 인쇄하는 편리한 옵션입니다. |
--project=<path> |
앱 프로젝트 디렉터리를 지정하는 옵션입니다. 먼저 프로젝트 디렉터리로 변경할 필요 없이 스크립트를 시작하려고 할 때 유용합니다. |
--port=<port> |
기본적으로 |
--adb=<file> |
adb 도구 실행 파일을 지정하는 옵션입니다. 실행 파일을 포함할 경로를 설정하지 않은 경우에만 필요합니다. |
-d -e -s <serial> |
이러한 플래그는 같은 이름을 가진 adb 명령과 유사합니다. 호스트 머신에 연결되어 있는 기기나 에뮬레이터가 여러 개인 경우 이러한 플래그를 설정합니다. 그 의미는 다음과 같습니다.
또는 특정 옵션을 사용할 필요 없이 특정 기기를 나열하도록 |
--exec=<file> -x <file> |
디버깅 중인 프로세스에 연결한 후 |
--nowait |
GDB가 연결할 때까지 Java 코드 일시중지를 비활성화합니다. 이 옵션을 설정하지 않으면 디버거에서 조기 중단점이 누락될 수 있습니다. |
--tui
-t |
텍스트 사용자 인터페이스가 지원된다면 이를 사용 설정합니다. |
--gnumake-flag=<flag> |
프로젝트 정보를 쿼리할 때 |
참고: 이 표의 마지막 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.