Proguard 난독화와 Crash Report Tool로 이슈 디버깅

프로젝트를 운영(유지보수)하면서 가장 중요하면서도 가장 기본이 되는 작업이 버그 리포트이다. 여기에선 Crash Report Tool로 Crashlytics를 사용했다. 그리고 회사 또는 팀의 정책, 작게는 개인에 따라 코드의 중요성이 높다면 난독화를 고민하게 되고 안드로이드에서는 무료인 Proguard 적용을 고려해보게 된다. (코드의 중요성이 낮더라도 한번 경험해보는 것도 좋다고 생각함) 하지만 난독화된 앱을 배포한 후 발생한 이슈를 디버깅하기 위해 Crash Report 콘솔에서 확인하면 이상한 문자를 접하게 된다.

Proguard 적용 전 이슈 발생했을 때

난독화가 되지 않은 앱을 디컴파일 해보면 소스 코드가 정상적으로 확인할 수 있다. 포함된 Android Support Library도 난독화가 되지 않은 상태이다.

그리고 앱에서 이슈를 발생시켜 보면 특정 함수에서 발생했으며 어떤 파일의 몇 번째 줄에서 발생했는데 ‘(MainActivity.java:21)을 통해서 알 수 있다.

public void forceCrash(View view) {
    throw new RuntimeException("This is a crash");
}

이슈는 다음과 같이 RuntimeException을 버튼 클릭 때 발생시키도록 만들었다.

Proguard 적용하기

프로젝트 생성 시 기본적으로 다음과 같이 build.gradle파일에 빌드 설정으로 다음과 같이 된다.

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

그리고 배포 시 Proguard 적용하기 위해서는 minifyEnabled를 true로 변경하면 된다.

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

ProGuard는 릴리스 모드(release)에서 빌드할 때는 적용되지만, 디버그 모드(debug)에서는 적용되지 않는다.

proguard를 적용해서 Signed APK파일을 만들고 디컴파일 했을 경우에는 위처럼 패키지부터 소스 파일까지 모두 특정 알파벳으로 난독화가 된 것을 확인할 수 있다.

앱에서 이슈를 발생시켜서 Crashlytics 콘솔에서 확인해보면 위에서 확인했던 이슈가 발생한 파일과 라인 수 부분이 Unknown Source로 변경되었다. 간단한 샘플 프로젝트이기 때문에 코드로 디버깅이 가능하지만 큰 규모의 프로젝트에서는 디버깅하는데 어려움을 겪을 수 있다.

그래서 proguard-rules.pro에 Proguard Rule을 추가하자.

-keepattributes SourceFile,LineNumberTable

다시 Proguard가 적용된 APK파일 생성하고 이슈를 발생 시켜보자.

Crashlytics를 확인하면 Unknown Source 대신에 이슈가 발생한 파일과 라인 수를 확인할 수 있다. 그리고 출력된 stack trace 오류에서 난독화된 패키지가 무엇인지 알고 싶다면 /outputs/mapping/release/mapping.txt 파일을 열어보자.

android.support.v4.app.Fragment -> android.support.v4.a.t:
    android.support.v4.util.SimpleArrayMap sClassMap -> aa
    java.lang.Object USE_DEFAULT_TRANSITION -> a
    int mState -> b
    android.view.View mAnimatingAway -> c
    int mStateAfterAnimating -> d
    android.os.Bundle mSavedFragmentState -> e
    android.util.SparseArray mSavedViewState -> f
    int mIndex -> g
    java.lang.String mWho -> h

Fragment가 속한 패키지는 android.support.v4.a.t로 변경된 것을 확인할 수 있으며 이에 속해 있는 변수나 함수들이 어떻게 변경되었는지 또한 확인할 수 있다. 난독화를 했다면 mapping.txt 파일은 보관해두고 만약 난독화된 코드의 stack trace를 디코딩하고 싶다면 mapping.txt를 이용해서 가능하기 때문이다.

retrace.bat -verbose mapping.txt stacktrace.txt > out.txt

out.txt파일에는 난독화된 코드의 stacktrace.txt가 해석된 stack trace가 출력된다.

ProGuard outputs the following files after it runs:

dump.txt
Describes the internal structure of all the class files in the .apk file
mapping.txt
Lists the mapping between the original and obfuscated class, method, and field names. This file is important when you receive a bug report from a release build, because it translates the obfuscated stack trace back to the original class, method, and member names. See Decoding Obfuscated Stack Traces for more information.
seeds.txt
Lists the classes and members that are not obfuscated
usage.txt
Lists the code that was stripped from the .apk

Proguard 사용하는 규칙

Proguard Manual – Proguard 사용 메뉴얼

-dontwarn [class_filter]
Specifies not to warn about unresolved references and other important problems at all. The optional filter is a regular expression; ProGuard doesn’t print warnings about classes with matching names. Ignoring warnings can be dangerous.
keep [,modifier,…] class_specification
Specifies classes and class members (fields and methods) to be preserved as entry points to your code.
-keepattributes [attribute_filter]
Specifies any optional attributes to be preserved. The attributes can be specified with one or more -keepattributes directives. The optional filter is a comma-separated list of attribute names that Java virtual machines and ProGuard support. Attribute names can contain ?, *, and ** wildcards, and they can be preceded by the ! negator.
-assumenosideeffects class_specification
Specifies methods that don’t have any side effects (other than maybe returning a value). In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren’t used. With some care, you can also use the option to remove logging code.

Proguard를 적용하고 Signed Apk를 생성할 때, 가끔 발생하는 이슈들이 있는데, 그 중 하나가 Referenced Class를 찾을 수 없어서 IOException이 발생했기 때문이죠.

오류 메시지를 보면 Please correct the above warnings first로 발생한 Warning들을 고쳐달라고 합니다.

Proguard 적용 중에 왜 Warning이 발생했는지 궁금하시면 Problem while processing에서 확인할 수 있어요. 이때 위에 있는 규칙들 중에서 맞는 규칙을 찾아 proguard-rules.pro에 추가해준다.

-dontwarn okio.**

위의 이슈는 okio 패키지에 있는 파일들에 대해선 Warning을 뜨지 않도록 다음과 같이 설정을 해주면 된다.

-keep class com.example.classname
-keepattributes attribute

# examples
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

만약에 Class 변환 중에 이슈가 발생하거나 외부 라이브러리의 Proguard 적용을 원하지 않을 경우, 해당 패키지의 파일들을 Proguard가 적용되지 않도록 설정이 가능하다. 구글 라이브러리의 경우, Proguard가 불필요하기 때문에 Proguard적용에서 제외시켜주는게 좋다. 그리고 보통은 외부 라이브러리를 추가할 때, Proguard 적용시 주의사항으로 규칙들을 제공해주고 있으므로 잘 확인해서 추가만 해준다면 크게 문제가 발생하지 않는다.

Twitter Flock Seoul 2015 – Fabric

Awesome ! Twitter Flock Seoul 2015

백앤드 개발자들을 통해 빌드 및 배포 자동화를 위해 fabric을 사용하고 있다는 이야기를 들은 적이 있다. 그리고 얼마전 알고 지내는 스타트업에서 fabric을 통해 배포 직전인 앱을 사람들의 이메일 등록을 통해 배포하는 것을 보았다. 물론 앞서 말한 두 개의 fabric은 서로 다른 이야기다. 이번 Twitter Flock 행사는 한국에서는 처음 열렸고, 모바일 개발자들에게 도움될 만한 주제들이 많았다.

먼저 패브릭(fabric)은 모바일 개발자들이 트위터에서 제공해주는 툴을 사용해 더 안정된 앱을 만들 수 있도록 도와주고 있다. 앱 개발에서의 안정성, 사용자 확보, 수익성, 사용자 인증 등을 해결하기 위해 여러가지 툴(Kit)를 내놓았고, Crashlytics, MoPub, Twitter Kit Answers 등이 있다.

App Stablilty(안정성)
  • Crashlytics : 모바일 충돌(오류) 감지 및 분석
  • Beta for Crashlytics : 앱 베타 오픈 테스트 관리
Identity(사용자 인증)
  • Digits : 전화번호를 통해 서비스 로그인
  • Log in with Twitter : 트위터 인증 로그인
Distribution(사용자 확성)
  • Twitter Kit : 네이비트 트윗 임베드, 드윗 컴포저 기능 제공
Mobile Analytics(사용자 분석)
  • Answers : 실시간으로 앱 최적화를 위한 분석
Monetization(수익성)
  • MoPub : 모바일 앱 개발자들을 위한 최고의 광고 플랫폼

더 자세한 사항은 패브릭(fabric)소개 에서 읽어 볼 수 있다.


행사 등록 (오후 13:00 ~ 14:00)

Flock은 개발자 컨퍼런스를 뜻하고, Fabric은 작년 10월 Twitter Flight 개발자 컨퍼런스에서 앱 제작을 지원하는 모듈식 개발 도구 모음이다. 장소는 학동역 부근 Patio9이었고 네임택을 받고 입장했을 때는 해외 기업 컨퍼런스라 그런지 다른 컨퍼런스와는 달리 클럽 조명과 음악으로 분위기가 더 좋았던 것 같다. 마치 2년전 샌프란시스코 TechCrunch를 갔었던 느낌이다. 세션 대부분은 Fabric 개발 도구를 만든 엔지니어, 개발자들의 세션이었고, 정보와 지식을 공유하기 위한 자리였다.

기조 연설, 데모, 파트너 성공 사례 (오후 14:00 ~ 15:00)

Twitter 코리아 대표가 나와 기조 연설을 했고, 왜 Fabric을 만들게 되었으며, 왜 사용해야하는지에 대해서 이야기를 들을 수 있었다. 그리고 이어서 파트너 성공 사례로 한국 스타트업의 개발 담당자들이 패널로 참석해 정보를 공유하는 자리를 가졌다.

현재 스타트업에서 Fabric 개발 도구 중 무엇을 어떻게 사용하고 있으며, 어떤 장점을 가지고 있는지 정보를 들을 수 있었고, 왜 스타트업에서 Fabric을 사용하면 좋은지에 대해서 들을 수 있는 자리였으며 ‘Between’을 개발한 VCNC, Flitto, ‘배달의 민족’의 우아한 형제들, ‘알람몬’의 말랑스튜디오 개발자 분들이 직접 앞에 나와 트위터 코리아 소영선 대표와 서로 질문과 답변식으로 대화를 나누었다. 사실 Fabric의 장점만 나열되는 것 같아 조금 아쉬운 질의응답 시간이었던 것 같다. 더 궁금하면 직접 실행으로 옮기자! 게을러지지 말자!

Digits: A Better Way to Login (오후 15:00 ~ 15:30)

우리가 대부분의 앱을 처음 사용할 때 거치는 첫 번째 단계는 회원 가입이다. 지루한 가입 단계로 인한 유입율을 높이기 위해서 대부분의 기업에서 페이스북, 트위터, 구글+ 로그인을 사용해서 수 십초 이내에 앱의 첫 화면을 볼 수 있도록 해주고 있다. 여기에 트위터는 더 좋은, 더 쉬운, 더 빠른 로그인 방법인 휴대폰 번호를 위한 인증을 내놓았다. 휴대폰 번호를 통한 인증은 보통 본인 인증때 우리가 사용하는 방식으로, 그 방법을 이용해서 회원 가입을 하도록 새로운 방안을 제시했다. 휴대폰 번호만 있으면 회원 가입이 가능하도록 하며 간편하고 그 만큼 안전하다고 한다. 무엇보다 개발자가 이를 개발하기 위한 단계도 굉장히 심플하게 만들었다. Fabric을 맥에 설치하면 상단 메뉴를 통해서 가이드와 관리를 할 수 있도록 제공해주고 있다.

Crashlytics: Quality First (오후 15:45 ~ 16:15)

대부분 현재 서비스하고 있는 기업이라면 Flurry, BugSense, Google Analytics 등을 통해 광고, 분석, 버그 추적 등을 하고 있을 것이다. 기본적으로 이를 사용하는 이유는 버그를 가진 앱을 배포했을 때 발생하는 피해, 앱 순위 하락과 좋지 못한 리뷰로 상처를 덜?받기 위해서(덜 받아도 상처는 상처) 그리고 개발 시간을 보다 단축시키기 위해서 사용한다. 이에 Twitter에서는 Crashlytics라는 도구를 만들었고 무료로 기업들이 사용할 수 있도록 배포하고 있다는 점, 또한 정말 사용하기 쉽도록 구현되어 있다는 것이다. 간단한 코드에 키를 등록해주면 자사 서비스와 연동이 되도록 만들어져 있다.

TwitterKit: Tap Into the Pulse of the Planet (오후 16:15 ~ 16:45)

예전에는 트윗을 임베드하기 위해서는 네이티브에 별도의 구현을 해야하기 때문에 비용이 많이 들었다. 이에 Twitter Kit은 코드 몇 줄을 통해 트윗 임베드를 편리하게 할 수 있도록 다양한 기능을 제공해주고 있다. 또한 트윗 컴포저는 앱 내에서 사용자가 트위터 팔로우들에게 사용자 자신만의 경험을 편리하게 공유할 수 있도록 제공해주는 기능이다. 디자인 또한 앱의 테마에 맞도록 커스텀하게 변경이 가능하여 스타일을 변경할 수 있다. 이 중에서 가장 필요했던 기능은 트위터 로그인(Log in with Twitter)인데, 기존의 트위터 로그인 인증시 사용자의 이메일을 알지 못했다. 이제는 사용자 동의를 통해서 사용자의 이메일을 수집할 수 있도록 기능을 제공해준다고 한다.

앞서 말한 모든 툴은 트위터에서 무료로 제공한다. 베타 버전 준비부터 서비스 오픈, 서비스 버그 관리, 사용자 분석, 개별 광고까지 모두 하나의 툴에서 할 수 있다는 점은 정말 놀랍다. 전화번호 인증, 크래시리틱스, 트위터의 타임라인 가쟈오기, 트위터로 공유하기, 앱에서 테마 수정 등 이 모든 툴을 사용하기 위해 필요한 것은 단 코드 몇줄이면 가능했다. 맥북 오른쪽 상단에 있는 패브릭 아이콘을 이용해서 베타 버전 배포를 위한 테스터 이메일 등록 후 배포, 툴을 사용하기 위핸 API 문서부터 코드까지 관리를 해주었고 코드를 복사/붙여넣기로 간단하게 개발할 수 있도록 되어 있었다. 패브릭은 개발자가 사용하는 개발 비용을 줄여주고 편리하게 개발할 수 있도록 정말 많은 노력을 기울였다는 생각이 들었고 많은 준비를 한 것 같다. 모바일 앱 개발자를 위한 정말 좋은 툴 하나가 나온 것 같다.

패브릭은 개발자 여러분이 사용하는 엑스코드(Xcode), 이클립스(Eclipse), 안드로이드 스튜디오(Android Studio), 인텔리제이(IntelliJ) 등의 IDE와 연동되어 있습니다. 패브릭은 또한 자동화된 코드 빌더와 테스트 툴과도 연동되어 있습니다. 덕분에 개발자 여러분은 키트의 업데이트에 대해 걱정할 필요가 없습니다. 패브릭이 업데이트가 올라올 때마다 여러분에게 알림을 줄 것이기 때문입니다. from 트위터 블로그