In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "what is the NativeCrash function of Android". In the daily operation, I believe that many people have doubts about the NativeCrash function of Android. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "what is the NativeCrash function of Android?" Next, please follow the editor to study!
A brief introduction to NE
The full name of NE is NativeException, which is an error generated during the operation of C or C++. NE is different from ordinary Java errors. Ordinary logcat cannot be directly restored to a readable stack and cannot be debugged without source code.
Therefore, daily application layer engineers, even if we have internal cloud diagnosis logs, generally ignore NE errors. When we encounter these problems, can engineers at the application layer who don't know much about C++ solve the problem of restoring the stack, locate or solve NE problems quickly?
The following will focus on:
1.1.The composition of so
Let's first understand the composition of so, a complete so consists of C code plus some debug information, this debug information will record the comparison table of all methods in so, that is, the corresponding table of method name and its offset address, also known as symbol table, this kind of so, also known as non-strip, is usually relatively large.
Usually, the so of release needs to go through a strip operation, so that the debug information in the so after strip will be stripped, and the size of the whole so will be reduced.
As shown in the following figure:
You can see the size comparison before and after the strip below.
If you don't know anything about NE or so, you can simply think of this debug information as a mapping file in Java code obfuscation, and only by owning this mapping file can you do stack analysis.
If the stack information is lost, basically the stack cannot be restored and the problem cannot be solved.
Therefore, these debug information is particularly important, which is the key information for us to analyze NE problems, so when we compile so, we must keep a copy of the so that has not been strip or the symbol table information that has been stripped off for later analysis, and each compiled so needs to be saved. Once the code is modified and recompiled, the symbol table information before and after modification will not correspond, nor can it be analyzed.
1.2.View so status
In fact, you can also check the status of so through the command line. You can use the file command under Mac. You can view some basic information of so in the return value of the command.
As shown in the following figure, stripped represents a so,with debug_info without debug information, and not stripped represents a so carrying debug information.
File libbreakpad-core-s.so
Libbreakpad-core-s.so: *, BuildID [sha1] = 54ad86d708f4dc0926ad220b098d2a9e71da235a, stripped
File libbreakpad-core.so
Libbreakpad-core.so: *, BuildID [sha1] = 54ad86d708f4dc0926ad220b098d2a9e71da235a, with debug_info, not stripped
If you are a Windows system, then I advise you to install a Linux subsystem, and then execute the same command in Linux, you can also get this information.
Next, let's take a look at how to get the so in both states.
1.3.Obtain strip and so that have not been strip
Currently, Android Studio outputs both strip and non-strip so regardless of whether it is compiled with mk or Cmake. For example, the following figure shows the two corresponding so generated by so compiled by Cmake.
So path before strip: build/intermediates/transforms/mergeJniLibs
So path after strip: build/intermediates/transforms/stripDebugSymbol
Alternatively, you can do strip,aarch74-linux-android-strip manually through aarch74-linux-android-strip, a tool provided by Android SDK. This tool is located in the / Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains directory.
There are many versions of this tool, which are mainly aimed at different mobile phone CPU architectures. If you don't know the CPU architecture of the mobile phone, you can connect to the mobile phone and use the following command to check:
Adb shell cat / proc/cpuinfo
Processor: AArch74 Processor rev 12 (aarch74)
As you can see in the figure above, my mobile phone CPU uses aarch74, so I use aarch74-linux-android-strip, the corresponding tool for aarch74. Since NDK provides many tools, you can use them later according to this principle:
Aarch74 architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch74-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch74-linux-android-strip
Arm architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-android-strip
You can directly strip the so of debug using the following command
Aarch74-linux-android-strip-strip-all libbreakpad-core.so
When compiling with Cmake, you can add the following command to compile the so of strip directly
# set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}-s")
# set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}-s")
When compiling with the mk file, you can add the following command, or you can compile the so of strip directly
-fvisibility=hidden
II. NE capture and parsing
As the name suggests, NE parsing is stack parsing. Of course, all the premise is to save a symbolic table, that is, the so that has not been strip. If you only have the so after strip, there is nothing you can do, and the stack can hardly be restored.
There are generally three ways to capture and restore the stack.
2.1By logcat capture
As the name implies, it is captured through logcat. When we open logcat through Android Studio and create a NE, we can only see a lot of symbols like # 00 pc 00000000000161a0, and there is no log that can be read directly. We want to directly output a log that can be read directly through logcat.
You can use ndk-stack, a tool provided under Android/SDK/NDK, which can directly parse the log output from NE into a readable log.
Ndk-stack is usually located under the tools of ndk, and the address under Mac is
/ Users/XXXX/Library/Android/sdk/ndk/21.3.6528147/ndk-stack
Then execute console commands in this directory, or in terminal of Android Studio
Adb shell logcat | androidsdk absolute path / ndk-stack-sym so directory
In this way, the console will output the following log when the NE occurs in the application. As you can see from the log, the so corresponding to the crash and the corresponding method name can be easily located if there is a source code for c.
Promote:~ njvivo$ adb shell logcat | ndk-stack-sym libbreakpad-core.so
* Crash dump: *
Build fingerprint: 'vivo/PD1809/PD1809:8.1.0/OPM1.171019.026/compil04252203:user/release-keys'
# 00 0x00000000000161a0 / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
# 01 0x00000000000090cc / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/oat/arm64/base.odex (offset 0x9000)
Crash dump is completed
In fact, the principle of ndk-stack is that the internal integration uses addr2line to parse the stack in real time and display it in the console.
Seeing some friends here, they think that this is not very simple, but the actual crash scenario is not easy to reproduce, and the user's scenario is sometimes difficult to simulate, so there are two ways to monitor and locate online NE crashes.
2.2.2.Through DropBox log parsing-- suitable for system applications
This is very simple. DropBox will record various logs of JE,NE,ANR. You only need to upload the log under DropBox for analysis and solution. A log example is posted below.
Resolution scenario 1:
With the ndk-stack tool above, you can directly parse the log under DropBox into a stack, from which you can see that it crashed in the Crash () method on line 111 of breakpad.cpp.
Ndk-stack-sym / Users/njvivo/Desktop/NE-dump data_app_native_crash@1605531663898.txt
* Crash dump: *
Build fingerprint: 'vivo/PD1809/PD1809:8.1.0/OPM1.171019.026/compil04252203:user/release-keys'
# 00 0x00000000000161a0 / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
Crash ()
/ Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111:8
Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo
/ Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:122:0
# 01 0x00000000000090cc / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/oat/arm64/base.odex (offset 0x9000)
Crash dump is completed
Resolution scenario 2:
Also use linux-android-addr2line, a tool provided by Android/SDK/NDK, which is located in the / Users/njvivo/Library/Android/sdk/ndk directory and has two versions.
Aarch74 architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch74-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch74-linux-android-addr2line
Arm architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line
The command is used as follows, and the crash address and method can also be parsed by combining the so that is not strip and the stack symbol 00000000000161a0 that appears in the log.
Aarch74-linux-android-addr2line-f-C-e libbreakpad-core.so 00000000000161a0
Crash ()
/ Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111
Based on the above, it seems very simple, but a fatal problem is that DropBox can only be accessed by system applications, and non-system applications can not get logs at all, so what should non-system applications do?
2.3. capture and parsing through BreakPad-applicable to all applications
Non-system applications can be monitored and analyzed through BreakPad, an open source tool provided by google. CrashSDK also uses this way to monitor the occurrence of NE in real time and record relevant files, so that crashes and corresponding application crashes can be reported together.
Here's a brief introduction to how to use BreakPad.
2.3.1, the implementation function of BreakPad
BreakPad mainly provides two functions: NE monitoring and callback, generating minidump files, that is, files at the end of dmp, and two additional tools, the symbol table tool and the stack restore tool.
Symbol table tool: used to extract debug information from so and get the symbol table corresponding to the stack.
Stack restore tool: used to restore dump files generated by BreakPad to symbols, that is, stack offset values.
These two tools are generated when compiling the BreakPad source code.
After compilation, there will be a minidump_stackwalk tool, and if some students do not want to compile, Android Studio itself also provides this tool.
This minidump_stackwalk program also exists in the Android Studio directory and can be used directly. If you do not want to compile, you can directly take it under this directory. The Mac path is:
/ Applications/Android Studio.app/Contents/bin/lldb/bin/minidump_stackwalk
2.3.2. The capture principle of BreakPad
It can be seen from the above that when an NE crash occurs in an application, BreakPad can write the minidump file corresponding to NE locally and call it back to the application layer. The application layer can do some processing in response to this crash to capture statistics. After uploading the minidump file, the actual stack can be restored with minidump_stackwalk and addr2line tools, as shown below:
When NE occurs in the application, BreakPad generates a dump file locally on the phone, as shown in the figure:
With the above files, we can only know that NE has occurred in the application, but these files are actually unreadable and need to be parsed.
Let's focus on how to analyze the NE generated above:
2.3.3. Parse the dump file
1. Get the dump file of NE crash, put the minidump_stackwalk and dump files in the same directory, or not, and enter the absolute path when filling in the path.
Then execute the following command in the terminal window in this directory, which indicates that the dump file is parsed with minidump_stackwalk, and the parsed information is output to the crashLog.txt file in the current directory.
. / minidump_stackwalk xxxxxxxx.dmp > crashLog.txt
2. After the execution, minidump_stackwalk will write the relevant information of NE to crashLog.txt, as shown in the figure:
3. According to the parsed NE information and paying attention to the red box in the figure, we can see that in the libbreakpad-core.so where the crash occurred, the 0x161a0 represents that the crash occurs at the location where the 161a0 is offset from the root position.
2.3.4. Get the crash stack
1. Using the addr2line tool mentioned earlier, according to the so file where Crash occurs and the offset address (0x161a0), you can get the method, the number of lines and the call stack relationship that generate crash.
2. Run the following command in the terminal window of its root directory pair.
Arm-linux-androideabi-addr2line-C-f-e ${SOPATH} ${Address}
-C-f / / print the name of the function where the number of error lines is located
-e / / print the corresponding path and number of lines of the error address
${SOPATH} / / so library path
${Address} / / address of stack error message to be converted. Multiple addresses can be added, but separated by spaces, for example: 0x161a0
3. The following figure is a real-life example.
Aarch74-linux-android-addr2line-f-C-e libbreakpad-core.so 0x161a0
Crash ()
/ Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111
As you can see from the figure above, the crash occurred on line 111 of the breakpad.cpp file, and the function name is Crash (), which is consistent with the real file. The crash code is as follows:
Void Crash () {volatile int * a = (int *) (NULL); * a = 1; / / here is 111line} extern "C" JNIEXPORT void JNICALLJava_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo (JNIEnv * env, jobject instance, jstring mLaunchInfoStr_) {DO_TRY {Crash () Const char * mLaunchInfoStr = env- > GetStringUTFChars (mLaunchInfoStr_, 0); launch_info = (char *) mLaunchInfoStr;// env- > ReleaseStringUTFChars (mLaunchInfoStr_, mLaunchInfoStr);} DO_CATCH ("updateLaunchInfo");}
Based on the above, the detailed stack information of NE parsed by the collected dump file can be applied.
Third, the extraction of so symbol table 3.1, extraction of so symbol table
From the above, we know that so contains some debug information, also known as symbol tables, so how do we separate these debug information out? ndk also provides us with relevant tools.
Aarch74 architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch74-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch74-linux-android-objdump
Arm architecture
/ Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-android-objdump
The following is how the command runs, which allows you to extract the debug information from so into a file.
Promote:~ njvivo$ aarch74-linux-android-objdump-S libbreakpad-core.so > breakpad.asm
3.2, symbol table analysis 3.2.1, direct analysis
The following figure shows the output symbol table file. Combined with the log above and the symbol table file below, we can also analyze the stack.
As shown in log, it has been indicated that the crash address is 161a0, and the corresponding code for 161a0 is * aq.1. From the above analysis, we already know that the crash is on line 111of breakpad.cpp, that is, the location of * axi1, which is exactly as expected.
Backtrace:
# 00 pc 00000000000161a0 / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
# 01 pc 00000000000090cc / data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/oat/arm64/base.odex (offset 0x9000)
3.2.2, tool parsing
Google provides a tool for Python that combines symbol tables with log to analyze the stack directly.
By executing the command, the relevant stack can be parsed, and the tool can be used for batch parsing on the server side, which is not described in detail here.
Python parse_stack.py
3.2.3. A brief analysis of the offset position
The above article mentioned the concept of an offset location, the author does not know much about this, but there is a general concept, C code has a root location of the code, each line of code has an offset position relative to the root code.
For example, in the example log above, there is a line of statement (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16), and + 16 represents a backward offset of 16 relative to the nUpdateLaunchInfo method.
As you can see from the figure above, the position of the nUpdateLaunchInfo method is 16190 with an offset of 16, that is, 16190 to 10 (10 from 16 to 10 after hexadecimal conversion) = 161a0, the same as the log output.
At this point, the study on "what is the NativeCrash function of Android" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.