Android System & AOSP Engineering/AOSP Framework & Custom Services

Android 디버깅 가이드: Logcat, dumpsys, strace, systrace 실무 활용법

임베디드 친구 2025. 4. 21. 14:02
반응형

안드로이드 환경에서 앱이나 시스템 서비스를 개발하다 보면 런타임에 원인 모를 크래시가 나거나, UI 프레임이 뚝뚝 끊기는 병목 현상을 마주하게 됩니다. 단순한 버그라면 자바 코드에 Log.d() 몇 줄 남기는 것으로 잡히지만, 여러 프로세스가 바인더(Binder)로 얽혀 있는 안드로이드 시스템 특성상 자바 로그만으로는 문제의 실마리조차 찾지 못할 때가 많습니다.

커널과의 상호작용, 백그라운드 서비스의 자원 점유 상태, 그래픽 렌더링 파이프라인의 지연 등 시스템 깊은 곳의 문제를 해결하려면 그에 맞는 전문적인 무기가 필요합니다. 이번 포스팅에서는 기본 로그 분석 도구인 Logcat을 시작으로 시스템 상태를 진단하는 dumpsys, 커널 시스템 콜을 추적하는 strace, 그리고 프레임 드롭을 잡아내는 systrace까지 실무에서 바로 써먹는 4대 디버깅 도구의 활용법을 AOSP 구조와 함께 풀어보겠습니다.

Generated by Gemini AI.

📌 핵심 요약 3줄

  1. 기본적인 애플리케이션 및 시스템 로그 제어는 Logcat 필터링과 로그 레벨 최적화를 통해 효율적으로 수행합니다.
  2. dumpsys와 strace를 활용하면 백그라운드 서비스의 실시간 메모리 상태와 프로세스 레벨의 커널 시스템 호출을 깊이 있게 진단할 수 있습니다.
  3. 시스템 병목과 프레임 드롭은 systrace로 시각화 분석하며, 로그의 근본적인 원인은 AOSP 프레임워크 소스 코드와 대조하여 추적합니다.

1. 안드로이드 4대 디버깅 도구 핵심 요약

디버깅을 시작하기 전, 내가 직면한 문제의 성격에 따라 어떤 도구를 꺼내 들어야 하는지 아는 것이 중요합니다. 각 도구의 분석 범위와 주 목적을 표로 정리했습니다.

디버깅 도구 주요 분석 대상 분석 레벨 권장 활용 시나리오
Logcat 앱 및 프레임워크 자바/네이티브 런타임 로그 애플리케이션 ~ 프레임워크 크래시 로그(Call Stack) 확인, 예외 처리(Exception) 추적
dumpsys 시스템 서비스(메모리, 액티비티, 배터리 등)의 정적 상태 프레임워크 내부 서비스 특정 앱의 메모리 누수 점검, 백그라운드 서비스 상태 진단
strace 프로세스가 커널에 요청하는 시스템 호출(System Call) 런타임 라이브러리 ~ 리눅스 커널 파일 I/O 지연 원인 분석, 권한 거부(Permission) 이슈 디버깅
systrace CPU 스케줄링, 그래픽 API 렌더링 락(Lock) 주기 시스템 전반 (하드웨어 동기화) 화면 버벅임(Jank) 분석, UI 프레임 드롭 원인 파악

2. Logcat을 활용한 효율적인 로그 필터링

가장 익숙한 도구이지만, 수많은 시스템 로그 속에서 내가 원하는 정보만 골라내는 필터링 기술이 핵심입니다.

Bash
 
# 1. 특정 태그(예: MyAppTag)를 가진 로그만 출력하고 나머지는 침묵(-s)
adb logcat -s MyAppTag

# 2. 시스템 전반의 로그 중 Error(E) 및 Fatal(F) 등급 이상의 심각한 로그만 필터링
adb logcat *:E

# 3. 단말기에 쌓인 기존 로그 버퍼를 깨끗이 비우기 (디버깅 시작 전 필수)
adb logcat -c

# 4. 현재까지의 로그 버퍼 내용을 파일로 덤프하고 프로세스 종료
adb logcat -d > log_dump.txt

3. dumpsys로 시스템 서비스 속 들여다보기

dumpsys는 현재 안드로이드 OS 위에 떠 있는 구글 핵심 서비스들의 메모리 스냅샷과 상태 인터페이스를 가감 없이 보여줍니다.

Bash
 
# 1. 현재 시스템에 등록되어 dumpsys로 조회 가능한 서비스 전체 목록 확인
adb shell dumpsys | grep "DUMP OF SERVICE"

# 2. 액티비티 매니저 서비스(AMS) 상태 분석 (현재 최상단 활성화된 화면 확인 등)
adb shell dumpsys activity top

# 3. 특정 패키지 앱이 점유하고 있는 힙(Heap) 메모리와 내부 세부 메모리(DRAM) 레이아웃 출력
adb shell dumpsys meminfo com.example.myapp

4. strace를 이용한 커널 시스템 호출(System Call) 분석

네이티브 C/C++ 레벨이나 HAL 드라이버단에서 파일에 접근하거나 프로세스 간 락이 걸려 멈추는 현상이 발생하면 strace가 답을 줍니다.

Bash
 
# 1. 타겟 앱의 프로세스 ID(PID)를 먼저 확인합니다.
adb shell ps -A | grep com.example.myapp

# 2. 확인된 PID(예: 1234)를 지정하여 해당 프로세스가 커널에 날리는 시스템 콜을 실시간 추적
adb shell strace -p 1234

# 3. 파일 열기(openat), 읽기(read), 쓰기(write) 관련 시스템 콜만 선택적으로 추적
adb shell strace -e openat,read,write -p 1234

5. systrace를 활용한 시스템 병목 및 성능 시각화

화면이 부드럽지 않고 버벅거리는 현상은 CPU와 GPU의 타이밍이 어긋나서 발생합니다. systrace는 시간 흐름에 따른 스케줄러와 그래픽 렌더링 상태를 타임라인 뷰로 그려줍니다.

Bash
 
# 안드로이드 SDK 툴 폴더로 이동 후 파이썬 스크립트 가동 (10초간 수집)
python systrace.py --time=10 -o my_trace.html sched gfx view amwm

결과물로 나온 my_trace.html 파일을 브라우저(Chrome)에 드래그하면 타임라인 형태로 시각화된 프레임 주기 분석 창이 나타납니다.


6. 디버깅 효율을 극대화하는 AOSP 소스 코드 활용법

로그에 찍힌 정체불명의 태그나 dumpsys가 뱉어낸 포맷팅의 의미를 정확히 파악하려면 결국 AOSP 프레임워크 코드를 열어봐야 합니다.

6.1 프레임워크 내부 로그 출처 역추적

시스템 로그에 "ActivityManager" 혹은 특정 경고 메세지가 찍혔다면, 로컬에 받아둔 AOSP 소스 루트 폴더에서 정적 검색을 수행하여 해당 로그를 출력한 주체를 찾아냅니다.

Bash
 
# 프레임워크 내부 자바 소스에서 해당 로그 문자열이 포함된 위치 검색
grep -rn "MyAppTag" frameworks/base/services/

6.2 dumpsys 출력 포맷 소스 확인

adb shell dumpsys activity를 쳤을 때 콘솔에 나오는 텍스트 양식은 아키텍처 내부의 dump() 메서드 안에 선언되어 있습니다. 이 형식과 내부 변수의 상관관계를 파악하려면 아래 프레임워크 코어를 대조해 보며 분석하면 됩니다.

  • 조회 파일 경로: frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
Java
 
// ActivityManagerService 내부의 dump 메서드 구현 예시
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
    
    // 이 구간에서 콘솔로 출력할 내부 상태 값들을 포맷팅합니다.
    pw.println("ACTIVITY MANAGER SYSTEM STATE (dumpsys activity)");
    mAtmInternal.dump(fd, pw, args, ...);
}

🛠️ 개발을 위한 팁 (Tips)

  1. 최신 단말(Android 10 이상)에서는 Perfetto 활용: 구글은 안드로이드 10 버전 이후부터 기존 systrace 시스템을 차세대 성능 분석 플랫폼인 Perfetto(페르페토)로 교체하고 있습니다. 파이썬 환경이나 자바 버전 이슈로 기존 systrace.py가 작동하지 않는다면 단말기 설정의 '개발자 옵션 -> 시스템 추적'을 켜서 트레이스 파일(.perfetto-trace)을 뽑아낸 뒤, 공식 웹 뷰어(ui.perfetto.dev)에 업로드하여 분석하시는 것이 최신 OS 기준 훨씬 정교한 타임라인 데이터를 보여줍니다.
  2. logcat -v threadtime 활용: 로그를 볼 때 단순히 메세지만 보지 마시고 타임스탬프 옆에 프로세스 ID와 스레드 ID가 같이 출력되는 -v threadtime 혹은 -v uid 옵션을 붙여서 보세요. 멀티스레드 환경에서 어떤 스레드가 번갈아가며 로그를 찍었는지 컨텍스트의 흐름을 파악하는 데 결정적인 단서가 됩니다.

⚠️ 흔히 하는 실수 (Common Mistakes)

  1. 상용 빌드(User Build)에서 strace 구동 시도: 양산되어 판매 중인 상용 안드로이드 스마트폰(User 빌드 펌웨어)에서는 보안상 strace나 dumpsys 일부 민감 기능의 접근이 리눅스 커널 권한 및 SELinux 정책에 의해 원천 차단됩니다. 해당 도구들을 제약 없이 원활하게 구동하여 테스트하려면 보드 빌드 시점에 lunch 선택 단계에서 반드시 userdebug 또는 eng 컴파일 옵션을 선택한 펌웨어를 디바이스에 플래싱해 두어야 합니다.
  2. logcat 버퍼 오버플로우로 인한 로그 유실: 시스템에 수많은 앱과 서비스가 돌고 있을 때 조건 없이 adb logcat을 걸어두면 로그 저장 버퍼(Ring Buffer)가 순식간에 꽉 차서 정작 내가 확인해야 하는 크래시 순간의 로그가 밀려나 삭제되는 현상이 발생합니다. 디버깅 전에는 필히 adb logcat -G 16M 처럼 로그 버퍼 사이즈를 충분히 확장해 두거나, 특정 태그만 파일로 실시간 스트리밍 저장(adb logcat -s MyTag > target.log)해야 데이터 유실을 막을 수 있습니다.

7. 결론

안드로이드의 다양한 디버깅 기법들은 단순한 에러 수정 도구를 넘어, 운영체제 하부 구조가 어떻게 상호작용하는지 가시적으로 보여주는 훌륭한 학습 도구이기도 합니다.

에러의 현상만 보고 코드를 짜 맞추기보다, dumpsys로 서비스 상태를 진단하고 strace로 커널 동작을 확증하며 AOSP 소스코드를 나침반 삼아 원인을 파고드는 습관을 들이면 트러블슈팅 시간을 드라마틱하게 단축할 수 있습니다. 오늘 다룬 도구들을 상황에 맞게 적절히 커스텀하여 시스템의 병목을 시원하게 뚫어보시길 바랍니다. 디버깅 도중 분석하기 어려운 로그나 크래시 덤프가 있다면 언제든 댓글로 남겨주세요!

반응형