제8회 kandroid 세미나의 "Application Framework Internals & Debugging" 발표시 사용했던, system_server 디버깅 기법에 대해 구체적으로 설명을 해야 할 듯 해서 아래의 글을 작성합니다. 먼저, 세미나시 발표했던 글에 대한 참조는 아래의 링크를 참조하세요.
위의 발표내용에서 이야기 했던 내용을 조금 정리하자면, 안드로이드 플랫폼에는 Binder IPC를 통해 접근할 수 있는 다양한 Binder Service들이 디폴트로 존재하는데 이러한 서비스를 제공하고 있는 프로세스는 크게 3가지로 구성된다는 것입니다. 1) system_server (Java 기반 Binder 서비스 + Native C++ 기반 Binder Service) 2) mediaserver (Native C++ 기반 Binder Service) 3) com.android.phone (Java 기반 Binder Service) 여기에서는 위의 Binder 서비스들중, system_server내에 존재하는 Java 기반 Binder 서비스들을 디버깅할 수 있는 방법을 설명하는 것이 목적입니다. 일반적으로 디버깅은 버그를 발견하고 줄이기 위해 사용하는 기법이지만, 여기에서는 system_server 내에 존재하는 Java 기반의 Binder 서비스를 런타임에서 추적할 수 있는 기반을 마련함으로써 해당 코드의 흐름을 효과적으로 분석하는 것을 목적으로 하고 있습니다.
더불어 여기에서는 구체적인 방법을 설명하기 위해, 일단 Gingerbread 버전의 안드로이드 플랫폼내에 포함되어 있는 system_server 프로세스를 대상으로 할 것입니다.
아래의 내용은 적절한 방법이 아는 듯 합니다. 아래의 덧글에 있듯이 tjrudals님의 방식이 최선의 방법인 듯 합니다. 아래쪽 글은 무시하는 것이 좋을 듯 합니다. 단지 기록 차원에서만 남겨놓습니다. - 2011년 10월 25일 업데이트 합니다. - |
------ 절차는 아래와 같습니다. (주의 : 아래의 절차보다는 덧글에 있는 tjrudals님의 방식 사용하세요.) ------------ 1. AOSP Git Repository에서 Gingerbread 코드를 다운로드 한다. 2. ./frameworks/base/core/java/android/app/ActivityThread.java 소스의 3609 라인을 아래와 같이 바꾼다. - android.ddm.DdmHandleAppName.setAppName("system_process"); + android.ddm.DdmHandleAppName.setAppName("org.kandroid.systemserver"); AppName을 org.kandroid.systemserver라는 형태로 바꾸는 것은 Eclipse에서 해당 프로세스에 디버거를 attach할 수 있도록 java process 규약을 따르기 위함입니다. 3. Target Device 또는 Emulator용 안드로이드 플랫폼 Image들을 빌드한다. 4. 위의 결과로 만들어진 Image를 사용해서, Target Device의 경우네는 ROM Image들을 대체하고, 에뮬레이터의 경우에는 플랫폼 Image들을 대체한 후 AVD를 생성한다. (주의: 최근 에뮬레이터의 경우엔, 3rd-Party Add-On Image를 빌드해서 설치한다고 하더라도 Default 플랫폼 이미지를 표준 안드로이드 플랫폼 이미지를 사용하는 것 같았습니다. 그러므로, 테스트를 위해서는 표준 안드로이드 플랫폼 이미지를 Backup 한 후, 해당 system.img를 새로 빌드한 것으로 대체한 후, AVD를 새로 생성하는 것이 좋습니다.) 5. 위의 과정을 통해 만들어진 Target Device 또는 AVD 기반에서 안드로이드 플랫폼을 구동시킨다. 그리고 나서, Eclipse를 실행한후 DDMS에서 org.kandroid.systemserver 프로세스가 실행되고 있는 지를 확인한다.
6. 이제 org.kandroid.systemserver를 디버깅하기 위한 Dummy 프로젝트를 생성한다. - Eclipse에서 안드로이드 프로젝트를 생성한다. - Target를 위해서 생성한 Emulator 또는 Device와 호환되는 Target을 지정한다. - 생성시 Default Activity는 생성하지 말고, package명은 org.kandroid.systemserver 로 명명한다. - 프로젝트 생성 후, Build Path -> Configure Build Path -> Libraries에서 android.jar를 제거한다. 7. Dummy 프로젝트에 디버깅에 필요한 Source를 추가한다. (src 폴더에 import -> File System을 통해 아래의 두개의 폴더를 import한다.) gingerbread/frameworks/base/services/java gingerbread/out/target/common/obj/JAVA_LIBRARIES/services_intermediates/src 8. Dummy 프로젝트에 디버깅에 필요한 5개의 Jar를 추가하고 해당 Jar에 대한 Source를 attach 한다. 방법은, Build Path -> Add Libraries -> User Library에서 4개의 Library를 추가하면 됨. android.policy - jar : gingerbread/out/target/common/obj/JAVA_LIBRARIES/android.test.runner_intermediates/classes.jar - source : gingerbread/frameworks/base/policy/src ext - jar : gingerbread/out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar - source : gingerbread/external framework - jar : gingerbread/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar - source : gingerbread/frameworks core - jar : gingerbread/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar - source : gingerbread/libcore
9. 이제 디버깅 하고자 하는 곳에 Break Point를 잡은 후, DDMS에서 org.kandroid.systemserver에 디버거를 attach 한다.
결과는 아래와 같다.
|