안드로이드 애플리케이션 소스를 디버깅하는 최선의 방법은 이클립스에서 [Debug As > Android Application]을 실행하는 것입니다. 그러나 어떤 경우에는 이 메뉴를 이용할 수 없거나 또는 이용할 필요가 없는 상황도 생깁니다.  
예를들어 Debug As 메뉴를 실행했더니 바빠 죽겠는데 어디가 꼬였는지(?) 계속 아래와 같은 에러가 발생한다면?

[2010-04-12 11:33:41 - Contacts]Installing Contacts.apk...
[2010-04-12 11:34:19 - Contacts]Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE
[2010-04-12 11:34:19 - Contacts]Please check logcat output for more details.
[2010-04-12 11:34:19 - Contacts]Launch canceled!

또는 로컬의 애플리케이션 소스가 타겟에 설치된 버전과 소스가 동일해서 재설치하거나 덮어쓸 필요가 없는데, 소스는 디버깅하고 싶다면?
이럴 때는 Debug As 메뉴를 고집하지 말고 임시로 수동으로 디버깅하면 됩니다. 

수동으로 프로세스에 디버거 붙이기
디버깅하고자 하는 애플리케이션 프로세스에 디버거를 여러분이 직접 수동으로 붙여서(attach) 디버깅할 수 있습니다. 다음 과정을 따릅니다.

  1. 타겟(에뮬레이터)에서 해당 애플리케이션을 시작시킴 
  2. 이클립스 DDMS에서 해당 프로세스를 선택
  3. 미리 만들어둔 리모트 디버그 실행설정을 실행함 
  4. 이제 소스에 중단점 존재시 디버그 퍼스펙티브로 전환됨

* 이클립스에 리모트 디버그 실행 설정 만들기
  • 프로젝트 오른 클릭 > Debug As > Debug Configurations 실행
  • Remote Java Application 타입으로 새로운 launch 설정 생성
  • Port를 8700번으로 수정
  • Apply 클릭 (Debug 클릭하면 바로 실행됨)


프로세스에 디버거 붙이는 작업을 자동화하기

만약 수동으로 디버거를 붙이는 작업을 자꾸 반복해야 한다면, 이것은 당연히 비효율적인 일이 되고 맙니다. 

또한 디버거를 붙이는 작업을 사람이 수동으로 처리하다보니, 애플리케이션 시작부터 리모트 디버거를 붙이기까지 다소 시간이 걸릴 수 있습니다. 이렇게 되면 디버거가 연결되기 전에 액티비티의 onCreate() 같은 메소드에 찍어둔 중단점은 지나쳐 버릴 수가 있습니다 (아 물론, 이 문제는 에뮬레이터의 Dev Tools 애플리케이션의 Development Settins에서 아래처럼 Wait For Debugger 옵션을 체크하여 방지할 수 있습니다).



어쨋든 디버거 붙이는 과정은 가급적 스크립트로 만들어두고 자동으로 실행시키는 것이 좋습니다.


▶ 타겟(에뮬레이터)에서 해당 애플리케이션을 시작

am(Activity Manager) 명령어를 이용합니다. 타겟에서 지정된 액티비티를 디버그 모드로 시작하는 명령형식은 다음과 같습니다.

am start -D -n <package-name>/<package-name>.<class-name> 

자동으로 해당 액티비티 프로세스의 디버깅 포트가 8700 포트로 포워딩되며 만약 8700 포트로 붙는 디버거가 없으면 액티비티는 디버거가 붙을 때까지 대기합니다. 다음은 Contacts 네이티브 애플리케이션의 주소록 목록화면 액티비티 띄우는 예제입니다.

$ adb shell am start -D -n com.android.contacts/.ContactsListActivity


▶ 이클립스 DDMS에서 해당 프로세스를 선택 

이클립스 DDMS를 보지 않고 방금 띄운 프로세스의 디버깅 포트를 알아내는 것이 핵심입니다. 디버깅 포트는 이렇게 알아낼 수 있습니다.

(1) 해당 프로세스가 마지막에 뜬 프로세스인 경우

adb jdwp | tail -1

(2) 프로세스의 이름을 알고 있는 경우

# ps| grep 프로세스명 | awk '{print $2}'
# 다음은 프로세스명이 android.process.acore인 경우 예제
$ adb shell ps | grep android.process.acore | awk '{print $2}'

이제 리모트 디버깅 실행설정에서 설정해둔 8700 포트를 이렇게 알아낸 포트로 포워딩하면 됩니다.

# 먼저 위에서 알아낸 디버깅 포트를 $DEBUG_PORT 변수에 저장합니다
$ adb forward tcp:8700 jdwp:$DEBUG_PORT


▶ 이클립스 리모트 디버그 실행설정을 실행
이클립스에 만들어둔 '리모트 디버그 실행설정'도 스크립트을 통해서 실행하는 방법이 있으면 좋겠네요. 이 부분은 좀더 찾아봐야겠습니다.

Posted by 에코지오
,