Android NDK 입문 (4) - native 크래시 디버깅 방법, addr2line과 Ghidra
·
모바일
3편까지는 어떤 크래시가 있고 어떻게 막는지를 다뤘다.그런데 운영 중 더 자주 부딪히는 건 이미 크래시가 난 상태에서 원인을 찾는 일이다.특히 막막한 시나리오가 있다.release 빌드, 사용자 단말, Crashlytics에서 받은 native 크래시 로그, 심볼은 stripped 상태.손에 있는 건 이렇게 생긴 시그널 번호와 fault 주소, 그리고 주소만 찍힌 backtrace뿐이다.signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0backtrace: #00 pc 0000000000041a70 /system/lib64/libc.so #01 pc 00000000000123bc /data/app/com.example/lib/arm64/libnat..
Android NDK 입문 (3) - AddressSanitizer, 스택 카나리 알고 네이티브 크래시 미리 막기
·
모바일
얼마 전 운영중인 앱이 native 코드 문제로 런타임에 죽었다.버퍼를 다루는 함수였다.Ghidra로 디스어셈블해 들어가다 __stack_chk_fail 호출 경로를 발견했다.스택 카나리가 buffer overflow를 잡아 죽인 거였다.크래시는 한 곳에서 막는 게 아니라 여러 층에서 걸러진다.카나리가 잡은 건 그중 한 층이었다.이번 편은 나도 공부하면서 그 층들을 정리해본다.미리 말하자면, 이번 편은 가볍게 읽고 넘어가도 된다. 이유는 이 것들을 본 순간 이미 당신의 앱은 죽어있다.본론으로 들어가, 2편에서 본 크래시들(SIGSEGV, SIGABRT, SIGBUS 등)을 막는 방어는 세 층으로 나뉜다.1층은 컴파일러와 런타임이 자동으로 해주는 것. NDK 빌드 시 이미 켜져 있음.2층은 도구로 잡는 것..
Android NDK 입문 (2) - SIGSEGV, SIGABRT, SIGBUS 네이티브 크래시 시그널 정리
·
모바일
native 크래시를 처음 만났을 때 가장 막막했던 건 어디서 났는지가 안 보인다는 점이었다.Java/Kotlin이었으면 NullPointerException이 어느 파일 몇 번 라인에서 났는지 stack trace에 다 찍힌다.native는 signal 11 (SIGSEGV) 같은 시그널 번호와 메모리 주소만 있었다.NDK 코드를 직접 안 짜도 이 로그는 만난다.의존하는 라이브러리가 내부적으로 native면 거기서 터진 게 시그널로 올라온다.이번 편은 그 시그널 종류를 정리해본다.시그널이 뭔지부터native 크래시는 전부 시그널로 옴.그래서 시그널이 뭔지부터 봄.시그널은 Unix 계열 OS가 프로세스에게 뭔가 잘못됐다고 알리는 메커니즘임.Android도 Linux 기반이라 같은 메커니즘을 씀.nativ..
Android NDK 입문 (1) - NDK를 왜 쓰는가, JNI와 네이티브 개발 기초
·
모바일
요새 온디바이스 AI 작업을 하고 있다.모델 추론 코드를 iOS와 Android에서 공용으로 쓰려고 native 모듈로 빼는 중.HAL 쪽도 native가 필요.오랜만에 NDK를 다시 만지다 보니 한동안 잊고 있던 것들이 다시 보였다.그래서 정리해봤다. 이번 편은 NDK를 왜 쓰는지, Java/Kotlin과 뭐가 다른지까지이다.NDK를 왜 쓰는가대부분의 Android 개발은 NDK 없이 끝남.화면 그리고 네트워크 호출하고 데이터 다루는 데는 Java/Kotlin만으로 부족함이 없음.그러다 어느 시점에 NDK가 강제되는 상황을 만남.보통 네 가지 중 하나임.첫째는 성능. AI 모델 추론, 미디어 인코딩/디코딩, 암호화 같은 무거운 연산은 JVM 위에서 한계가 있음. TensorFlow Lite, ONNX ..