For Android Native developers, they may often encounter the problem of Native Crash in the development process and online environment. For such Native Crash, we usually directly adDR2line or use the NDK-Stack script attached to NDK for analysis. However, the NDK-Stack does not analyze libraries with mismatched build ids. For the above problems, we can try to analyze them even if the build ID is different. The general process is as follows:
Based on this analysis process, I wrote an AS plug-in: SmartNDKStack, which has the following functions:
- You can upload logs or select log analysis. Hyperlinks are displayed for parsing results
- Resolve based on function offset when buildId does not match
- Expand inline call
- Select the ELF file to resolve the build ID in the Project view
- Specify the NDK path
- Specify the symbol library directory
If you need it, you can search for it in the plugin market. Now there may be some shortcomings, if there is a problem, please send me the screenshots and symptom description: [email protected]
The following is a description of the principle.
1. Description of call stack frame content
Write a demo to trigger crash
__attribute__((always_inline)) void realThrowFatal(a){
raise(SIGABRT);
}
__attribute__((always_inline)) void throwFatal(a){
realThrowFatal(a); }extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
throwFatal(a);return env->NewStringUTF(hello.c_str());
}
Copy the code
Run the call stack
The 2021-11-14 16:04:45. 573, 14705-14705 /? A/DEBUG: #00 pc 00000000000c5008 /apex/com.android.runtime/lib64/bionic/libc.so (tgkill+8) (BuildId: E81bf516b888e895d4e757da439c8117) 2021-11-14 16:04:45.? 574, 14705-14705 / A/DEBUG: #01 pc 000000000000f0c8 /data/app/~~NiGDTVWkvUzCYf_UpH7RdQ==/com.example.ndkdemo-dfk3WrVVoUG5N0jUHQiyyw==/lib/arm64/libndkdemo.so (Java_com_example_ndkdemo_MainActivity_stringFromJNI+52) (BuildId: 8 c26841b3c32a89935d095d8e916180628bded7b) 16:04:45. 2021-11-14? 574, 14705-14705 / A/DEBUG: #02 pc 000000000013ced4 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: 9f1408149c58982ae91ee6377c202d2b) ...Copy the code
The image version:
For the above call stack,# 01
Is the most concerned developers, hanging in their own library.
The key message reads as follows:
- The absolute path of the crash library on the local machine is
/data/app/~~NiGDTVWkvUzCYf_UpH7RdQ==/com.example.ndkdemo-dfk3WrVVoUG5N0jUHQiyyw==/lib/arm64/libndkdemo.so
- The offset of the crash address relative to the library is
0xf0c8
- Crash address is in the function
Java_com_example_ndkdemo_MainActivity_stringFromJNI
, the offset with respect to the function address is52 (Decimal)
- The BuildId of crash’s library is
8c26841b3c32a89935d095d8e916180628bded7b
2. How to parse
-
Normal operation
addr2line -Cfie libndkdemo.so 0xf0c8
Most tutorials on the Internet are conducted directly with the above adDR2line operation, which can indeed quickly locate the crash caused by direct operation in the development process. However, if the code has changed and the library does not match, the locating efficiency will be greatly reduced. For example, the test reported the crash, but the local code has changed and the library does not match. If you want to get a library with the same build ID, go back to the original code and create a new library with the same build ID for addr2line.
-
Advanced operation
As shown in the above flow chart, we can first confirm the address of the function in the local library, and then add the address with the offset of the function to get the new address for resolution.
-
Get function address
-
parsing
The address of the function is 0xf094, plus 52 in decimal, which means 0xf094 + 0x34 is exactly 0xf0C8, matching. We can still use this scheme resolution in the case of changes to the local library file (but make sure the change is not related to the current function).
-
The local library has changed
Modify other functions so that the address of the function where crash is located is changed. After the change, the address of the function is 0xf0A0, 0xf0A0 + 0x34 = 0xf0D4. The new address addr2line is used, which can be found. 8 c26841b3c32a89935d095d8e916180628bded7b), but it can still parsing.
-