본문 바로가기
  • Survival Plan
IT 이야기

ADB와 Logcat 이용하여 스마트폰 디버깅

by IT/머신러닝 엔지니어의 독서/경제/육아 공부 리치윈드 - windFlex 2020. 3. 16.

모바일 어플을 개발하면서 답답함을 느낄 때가 자주 발생하곤 합니다.

 

Android x Logacat

그 이유는, 기존 PC / Desktop / Server 용 어플리케이션 개발은 익숙한 환경에서 로그를 확인 할 수 있지만,

모바일 환경은 그게 어렵기 때문이죠.

가뜩이나, 모바일은 권한 자체도 admin 권한이 아니기 때문에 더욱 그러합니다. 

마치 Guest User로 원격지에 있는 PC를 사용하는 느낌이랄까요?

 

대표적으로, 모바일 어플이 찍어주는 콘솔로그를 보고 싶은 경우입니다. 

 

한마디로 

가. 시. 화

가 안된다는 거죠.

 

( 디버그 환경에서는 콘솔로그 창을 별도로 열고 있기 때문에, 로그 레벨별로 확인이 가능하지만, 

  On Device에서 구동되는 것은 콘솔로그가 보이지 않는다. )

 

이렇게 모바일 환경에서 로그를 확인하고자 할 때,

로그 덤프 (Log Dump)를 해주는 툴이 있는데, 바로...

Logcat

logcat은 기기에서 오류와메세지가 발생할 때, 시스템 메세지의 로그를 텀프해서 보여 줍니다.

Linux 등 Desktop OS에는 다양한 로그를 쌓고 이러한 로그를 여러 옵션으로 Dump 해주는 시스템이 있는데, logcat은 이들의 하위 호환 정도로 보면 되겠습니다. 

 

대부분은 발생하지 않지만,

특정 상황에만 확률적으로 발생하는 에러를 파악하려면

logcat으로 로그를 살펴보는 것이 첫번째 입니다. 

 

실 사례를 예로 든다면, 

 

제 경우 어플을 Release 모드로 제 디바이스에 설치/실행 했을 때는 정상 동작 하지만,

play store를 통해서 다운로드/설치하면 비정상 종료를 하는 경우로 예를 들 수 있습니다 

이런 경우 실제 에러를 발생 시키는 단말에서, 시스템 로그/어플에서 발생하는 로그를 봐야만 원인 분석이 쉽겠지요.

 


[ ADB ( Android Debug Bridge ) ]

logcat을 실행시키기 위해서는 로그를 보고자 하는 단말 (Device)와 연결이 되고, 제어를 할 수 있어야 합니다. 

Device와 연결이 되어 있어야 뭘 보든지 찾든지 하겠죠?

이렇게 개발용 PC - Android Device 간 연결 및 제어를 지원하는 ADB (Android Debug Bridge) 라는 도구를 사용합니다. 

더보기

[디버그 포트/채널]

물리적인 제조사에는 별도의 접근 방법들이 더 있습니다.  JTAG 또는 그 이상의 고가 장비를 이용한 Debug Channel 이 있지만, 우리가 Device hacking 할것도 아니고, 이런것은 건너 뛰도록 하겠습니다. 

 

ADB는 안드로이드 스튜디오(Android Studio)가 설치되어 있다면, Android Studio 내부에 포함되어 있습니다. 

 

[Windows]

(개인마다 Setting값에 차이가 있겠으나) Android Studio를 설치 후  기본환경을 고려하면 

c:\Users\User\AppData\Local\Android\sdk\platform-tools 경로에 adb.exe가 존재 합니다. 

앞부분의 경로는 환경에 따라 달라질 수 있고, 안드로이드 스튜디오의 경로 아래 platform-tools를 찾으시면 됩니다. 

 

[Mac OS]

맥북의 경우, 역시나 안드로이드 스튜디오에서 경로에서 찾을 수 있습니다. 그러나 방법은 2가지가 있습니다. 

 

1) 우선 첫번째 안드로이드 스튜디오 경로를 찾기 위해서, 안드로이드 슈튜디오 메인 메뉴에서의 Preferences... 메뉴로 들어 갑니다. 

Android Studio > Preferences....

ADB 명령어의 경로 확인:

System Settings > Android SDK에서 기본 라이브러리의 경로를 확인합니다. 

 

제 경우에는 ~/Library/Android/sdk/platform-tools/ 경로에 adb 명령어가 있는 것을 확인 할 수 있습니다. 

그러나 .. 

저는 무쟈게 귀찮 더라구요. 

그냥 Homebrew로 설치해서 사용합니다. 

 

brew install android-platform-tools

혹시 설치 에러가 나면,

더보기

brew install android-platform-tools
Error: No available formula with the name "android-platform-tools"
Found a cask named "android-platform-tools" instead. Try
  brew cask install android-platform-tools

brew cask install android-platform-tools

 

위와 같이 homebrew 를 이용해 인스톨을 하면, 그냥 자동으로 환경 세팅 해 줍니다. 


[device 연결 확인]

adb 명령어가 준비 되었다면, Device가 제대로 연결되어 있는지 확인 해야 합니다. 

adb 에는 다양한 문구가 있지만, 이번 포스팅에서는 adb devices와 adb shell 만 사용할 예정입니다. 

 

아래 명령을 입력하여 연결되어 있는 장치(Device)를 확인합니다. 

$ adb devices

안드로이드 스튜디오의 에뮬레이터만 연결되어 있는 상황입니다.

실제 스마트폰 단말을 연결한 후, 다시 연결성 확인을 합니다. 

스마트폰을 붙였을 때, unauthorized 라는 문구가 출력됩니다.

adb로 연결을 되었으나, 권한이 없다고 합니다. 

이는 스마트폰에서 개발자/디버그 권한이 설정되지 않았기 때문입니다. 

USB 디버깅 권한이 설정 되었다면, USB를 연결할 때 위와 같은 선택 메뉴가 나옵니다. 

"허용"으로 눌러 줍시다. 

간혹, 스마트폰 화면이 잠금으로 된 상태에서 USB를 연결하면, 선택화면이 뜨지 않을 때도 있습니다. 

이런 경우는, 스마트폰 잠금을 해제하고 화면이 켜져 있는 상태에서 USB를 다시 연결 해 주세요.

 

USB 디버깅 허용으로 선택하고, 다시 adb devices 명령을 실행하면, 

attached 함공이 "device"로 변경된것을 확인 할 수 있습니다. 

 

USB 디버깅 권한 허용 후 adb devices를 실행

 

참고로, 스마트폰에서 USB 디비깅 옵션 설절이 안되어 있는 경우는 아래를 참조해 주세요. 안드로이드 설정 메뉴에서 몇개 버튼 꾹꾹 눌러주면 됩니다. 

[스마트폰 USB 디버깅 옵션 켜기]

더보기

 

 요약하면 아래와 같습니다. 

  1) Android의 Setting 어플 실행

  2) 소프트웨어 업데이트 메뉴 진입

  3) 빌드번호 연속 누름 (7~10회)

  4) 다시, 소프트웨어 업데이트 메뉴로 나와서, "{} 개발자 옵션" 생성 확인

  5) "{} 개발자 옵션}" 진입 후, "USB 디버깅" 사용으로 변경

  6) USB로 스마트폰 연결 후, USB 디버깅 "허용" 버튼 선택

 

상세 내용은 아래 포스팅을 참조 바랍니다. 

https://windflex.tistory.com/38

 

안드로이드 개발자 옵션 및 디버깅 옵션 켜기

[ 개발자 옵션 켜기 / USB 디버깅 옵션 켜기 ] 스마트폰을 USB로 연결하여 디버깅을 하거나, Shell에 붙어서 무엇인가를 하려면, 개발자 옵션을 켜 주어야 합니다. 간혹, USB를 연결하고도 ADB (Android Debugging..

windflex.tistory.com

 


자 이제 PC와 스마트폰 간 연결은 해 놨으니 이제 진짜 로그를 한번 보시지요.

logcat 명령어는 다음과 같은 구조를 가지고 있습니다. 

[adb] logcat [<option>] ... [<filter-spec>] ...

locat 명령어의 옵션을 먼저 써주고, 다음에는 필터링 설정을 써주는 식입니다. 

 

상세 저기 아래 숨김 박스를 참조해 주시고요. 

기본 실행은 단순합니다. 

$ adb logcat

혹은, 스마트폰의 shell 로 접속을 해서, 스마트폰 내부에서 logcat을 실행 해도 동일 합니다. 

$ adb shell
# logcat

 

그런데, 이렇게 실행하면 모든 로그들이 출력이 되어서 뭐가 뭔지 알아 볼 수가 없습니다. 

일단 여러 옵션을 걸어주어서 필요한 부분으로 최소화 하는 작업이 필요합니다. 

 

주요 옵션들만 살펴 보면, 

-c : clear 옵션

-v : 출력 형태 설정 옵션

-d : 출력후 종료 옵션

-s : 출력 로그의 우선순위 레벨 설정


 

-v [형식] : 출력 형태 옵션 상세

   [형식 유형]

  • brief : 우선순위/태그 + PID 
  • process : PID만 
  • tag : 우선순위/태그만 
  • thread : 프로세스:쓰레드 + 우선순위/태그 
  • raw : 다른 데이터 없이 로그만 출력 
  • time : 날짜 + 시간 + 우선순위/태그 + PID 
  • long : 모든데이터를 출력하고 빈줄로 로그들을 구분함

사용의 예는 다음과 같습니다. 

너무 많은 로그 때문에 tail -n 5로 다섯 항목만 출력 했습니다. 바로 종료 하기 위해 -d 옵션을 추가 했습니다. 

[출력 옵션]

 

옵션들 보다 더욱 유용한 것이, 필터링 우선순위 입니다. 

Log의 양이 너무 방대하기 때문에, 로그의 수준별도 필터링을 하는 것입니다. 

 

Warning Log를 출력할 것인가? Error 로그 이상만을 출력할 것인가...? 를 정하는 것이라고 보면 됩니다. 

당연히 낮은 우선순위로 설정 하면, 설정값 이상은 모두 출력 됩니다. 

 

예를 들면, Warning 출력으로 할 경우, Warning 보다 우선순위가 높은 Error 와 Fatal, Silent 등의 로그는 포함되어 출력됩니다. 

반대로 Warning 보다 우선순위가 낮은 Debug, Info 는 출력되지 않습니다. 

만약 출력 필터링 우선순위를 S로 설정하면, 대부분의 경우는 아무것도 출력 되지 않습니다. 

(아래 우선 순위는 V < D < I < W < E < F < S 순서 입니다. )

 

  • V: Verbose(가장 낮은 우선순위)
  • D: Debug
  • I: Info
  • W: Warning
  • E: Error
  • F: Fatal
  • S: Silent(가장 높은 순위, 이 경우 아무것도 출력되지 않음)

다음은 간략히 Error 레벨의 로그를 출력한 예입니다.

$ adb logcat -d -s *:E | tail -n 5

저는 주로 아래와 같은 형태로 명령어를 사용합니다. 

adb logcat -d -s *:E | grep -E "samsung" | tail -n 5

위의 의미는 Error 레벨 이상만을 출력하고, 그중에서 "samsung" 키워드 패턴으로 출력하라는 뜻입니다. 

뒤의 tail -n 5는 편의상 짧게 보려고 붙여놓은 파이프 입니다. (현재 포스트상 의미 없습니다.)

주로 사용하는 형태

스크린 샷 잡고 나서 보니, 제 스마트폰의 Samung Note가 뭔가 지원을 못받고 있어서, 예외 루틴으로 들어 갔네요. 

SDK 지원이 안되고, 이 때문에 뭔가 로드를 못했고, 여러번 시도 했는데 결국 안되었다는 내용이 보입니다. 

api.samsungcloud.com에 접속을 하려고 했는데 DNS를 인식을 못했거나, 네트워크 연결이 안되었나 봅니다. ^^;;;;;

 

 

[ logcat 옵션 상세]

더보기

옵션

다음 표는 logcat의 명령줄 옵션을 설명합니다.

옵션설명
-b <buffer> 보기 위한 대체 로그 버퍼를 로드합니다(예: events 또는 radio). main, system  crash 버퍼 세트가 기본적으로 사용됩니다. 대체 로그 버퍼 보기를 참조하세요.
-c, --clear 선택한 버퍼를 지우고(플러시하고) 종료합니다. 기본 버퍼 세트는 main, system, crash입니다. 모든 버퍼를 지우려면 -b all -c를 사용합니다.
-e <expr>, --regex=<expr> 로그 메시지가 <expr>과 일치하는 줄만 출력합니다. 여기서 <expr>은 정규 표현식입니다.
-m <count>, --max-count=<count> <count>개 줄을 출력한 후 종료합니다. --regex와의 페어링이 필요하지만 자체적으로도 작동합니다.
--print --regex  --max-count와 페어링하면 콘텐츠가 정규식 필터를 우회할 수 있지만, 여전히 올바른 일치 숫자에서 중지합니다.
-d 로그를 화면에 덤프하고 종료합니다.
-f <filename> 로그 메시지 출력을 <filename>에 씁니다. 기본값은 stdout입니다.
-g, --buffer-size 지정된 로그 버퍼의 크기를 출력하고 종료합니다.
-n <count> 순환되는 로그의 최대 수를 <count>로 설정합니다. 기본값은 4입니다. -r 옵션이 필요합니다.
-r <kbytes> <kbytes> 출력마다 로그 파일을 순환시킵니다. 기본값은 16입니다. -f 옵션이 필요합니다.
-s 모든 태그의 우선순위를 'silent'로 설정하는 필터 표현식 '*:S'와 동일하며, 콘텐츠를 추가하는 필터 표현식 목록 앞에 두기 위해 사용합니다. 자세한 내용은 로그 출력 필터링 섹션을 참조하세요.
-v <format> 로그 메시지의 출력 형식을 설정합니다. 기본값은 threadtime 형식입니다. 지원되는 형식의 목록은 로그 출력 형식 제어 섹션을 참조하세요.
-D, --dividers 각 로그 버퍼 간의 구분선을 출력합니다.
-c 전체 로그를 플러시하고(지우고) 종료합니다.
-t <count> 가장 최근의 줄 수만 출력합니다. 이 옵션은 -d 기능을 포함합니다.
-t '<time>' 지정된 시간 이후 가장 최근의 줄을 출력합니다. 이 옵션은 -d 기능을 포함합니다. 공백이 있는 매개변수에 따옴표를 사용하는 방법에 관한 자세한 내용은 -P 옵션을 참조하세요.

 

-T <count> 지정된 시간 이후 가장 최근의 줄 수를 출력합니다. 이 옵션은 -d 기능을 포함하지 않습니다.
-T '<time>' 지정된 시간 이후 가장 최근의 줄을 출력합니다. 이 옵션은 -d 기능을 포함하지 않습니다. 공백이 있는 매개변수에 따옴표를 사용하는 방법에 관한 자세한 내용은 -P 옵션을 참조하세요.

 

-L, -last 마지막 재부팅 전에 로그를 덤프합니다.
-B, --binary 로그를 바이너리로 출력합니다.
-S, --statistics 로그 스패머를 식별하고 타겟팅할 수 있도록 통계를 출력에 포함합니다.
-G <size> 로그 링 버퍼의 크기를 설정합니다. K 또는 M을 끝에 추가하여 킬로바이트나 메가바이트를 표시합니다.
-p, --prune 현재의 허용 목록과 차단 목록을 출력하고(읽고) 다음과 같이 인수를 사용하지 않습니다.

 

-P '<list> ...'
--prune '<list> ...' -P '<white_and_black_list>'
허용 목록과 차단 목록을 작성(설정)하여 특정 목적을 위한 로깅 콘텐츠를 조정합니다. <white>  ~<black> 목록 항목의 혼합된 콘텐츠를 제공합니다. 여기서 <white> 또는 <black>은 UID, UID/PID 또는 /PID일 수 있습니다. logcat 통계(logcat -S)의 지침에 따라 다음과 같은 목적으로 허용 목록과 차단 목록을 조정할 수 있습니다.
  • UID 선택을 통해 특정 로깅 콘텐츠에 가장 긴 수명을 제공합니다.
  • 차단 목록 who(UID) 또는 what(PID)은 logspan을 늘리기 위해 이러한 리소스를 사용합니다. 그러면 진단 중인 문제를 더 잘 볼 수 있습니다.

기본적으로 로깅 시스템은 로그 통계에서 최악의 위반자를 자동으로 차단 목록에 추가하여 새로운 로그 메시지를 위한 공간을 동적으로 만듭니다. 휴리스틱이 고갈되면 시스템은 가장 오래된 항목을 잘라내어 새 메시지를 위한 공간은 만듭니다.

허용 목록을 추가하면 AID(Android Identification Number)가 보호되어 프로세스의 AID 및 GID가 위반자로 선언되는 것을 방지할 수 있으며, 차단 목록을 추가하면 최악의 위반자로 간주되기 전에 공간을 확보할 수 있습니다. 잘라내기를 얼마나 적극적으로 할지 선택할 수 있습니다. 또한 각 로그 버퍼의 가장 오래된 항목에서만 콘텐츠를 삭제하도록 잘라내기를 해제할 수도 있습니다.

따옴표

adb logcat은 따옴표를 유지하지 않으므로 허용 목록과 차단 목록을 지정하기 위한 구문은 다음과 같습니다.

 

다음 예제는 PID 32676 및 UID 675로 허용 목록을 지정하고, PID 32677 및 UID 897로 차단 목록을 지정합니다. 더 빠른 잘라내기를 위해 차단 목록의 PID 32677에는 가중치가 적용됩니다.

 

사용할 수 있는 다른 차단 목록 및 허용 목록 명령어 변형은 다음과 같습니다.

 

--pid=<pid> ... 지정된 PID의 로그만 출력합니다.
--wrap 두 시간 동안 절전 모드일 때 또는 버퍼가 래핑하려고 할 때 중 하나가 먼저 발생하는 경우 about-to-wrap wakeup을 제공하여 폴링의 효율성을 높입니다.

 


 

다음은 구글의 안드로이드 개발자 사이트에 게시된 logcat 가이드 입니다. 

 

https://developer.android.com/studio/command-line/logcat

 

logcat 명령줄 도구  |  Android 개발자  |  Android Developers

Logcat은 기기에서 오류와 메시지(앱에서 Log 클래스로 작성)가 표시될 때 스택 추적을 비롯하여 시스템 메시지의 로그를 덤프하는 명령줄 도구입니다.

developer.android.com


긴 글을 읽어 주셔서 감사 드립니다. 꾸벅 !!!

유용한 글이 되었다면, 좋아요~와 구독 부탁 드립니다. 

 

댓글0