brief introduction
NE, the full name of Native Exception, in Android, mainly refers to exceptions in native programs or natvie libraries running in user space.
NE problems usually lead to program collapse, resulting in unstable functional modules.
Common types of NE problems
The following describes several common Native Crash situations:
-
Actively throwing an exception, calling abort() in the code, the system sends the signal SIGABRT(6) to the process. This problem is usually implemented by the code to the abnormal branch. It needs to check to see what conditions result, and CamX code is used more.
-
The process is killed by SIGKILL(9). For example, it is killed by adb shell kill -9 $PID or a process management mechanism. The APP process may encounter this problem and generally does not generate a tombstone file.
-
Null pointer. In the address space of the process, the permission of the first page starting from 0 is set to be unreadable and writable. When the instruction of the process attempts to access the address in the page (such as reading the memory pointed by the null pointer), the processor will generate an exception, and then the Linux kernel will send a segment error signal SIGSEGV(11) to the process
-
The wild pointer refers to an invalid address. If the address is unreadable and writable, it will crash immediately (the kernel sends a segment error signal SIGSEGV to the process). At this time, the bug will be found soon.
If the accessed address is writable and the memory is modified through the wild pointer, it is likely that Crash will occur after a period of time (after other codes use the memory). At this time, the call stack displayed when viewing Crash may not be related to the code part where the wild pointer is located. It is a kind of memory.
-
Array out of bounds / buffer overflow. The situation is similar to that of a wild pointer. It accesses an invalid address and steps on someone else's memory area.
Common debugging tools
The debugging tool is to help us locate the point where the problem occurs. (I tried, but failed. I prompted that the file format of so is wrong, and the location content should be consistent with that of backtrace.)
Arm linux Android addr2line is a tool provided in NDK to convert memory addresses into line numbers. Generally, the specific point is to locate the specific line in the file according to the offset memory address in various logs, such as so library logs contained in trace logs and tometone logs.
Reference link:
https://blog.csdn.net/yanzheng1113/article/details/8148091
https://blog.csdn.net/tkwxty/article/details/103493624
Relevant instructions:
ubuntu@ubuntu:~$ arm-linux-androideabi-addr2line --h
Usage: arm-linux-androideabi-addr2line [option(s)] [addr(s)] Convert addresses into line number/file name pairs. If no addresses are specified on the command line, they will be read from stdin The options are: @<file> Read options from <file> -a --addresses Show addresses -b --target=<bfdname> Set the binary file format -e --exe=<executable> Set the input file name (default is a.out) -i --inlines Unwind inlined functions -j --section=<name> Read section-relative offsets instead of addresses -p --pretty-print Make the output easier to read for humans -s --basenames Strip directory names -f --functions Show function names -C --demangle[=style] Demangle function names -h --help Display this information -v --version Display the program's version arm-linux-androideabi-addr2line: supported targets: elf32-littlearm elf32-bigarm elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex Report bugs to <http://www.sourceware.org/bugzilla/>
We often use:
arm-linux-androideabi-addr2line -e To be debugged so Library path memory address
The addr2line tool is integrated in both NDK and Android source code. Here I take the Android source code as a demonstration. We can find many addr2line files through search. We need to choose the one suitable for ourselves. We use arm linux Android addr2line
find . -name *addr2line*
./kernel-4.19-lc/scripts/faddr2line ./kernel-5.10/scripts/faddr2line ./ccu_tool/md32ccu/ToolChain/install_md32/share/man/man1/md32-elf-addr2line.1 ./prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line ./prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-addr2line ./prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-addr2line ./prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/aarch64-elf-addr2line ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/share/doc/binutils.html/addr2line.html ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/share/man/man1/aarch64-elf-addr2line.1 ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin/aarch64-none-elf-addr2line ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/share/doc/binutils.html/addr2line.html ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/share/man/man1/aarch64-none-elf-addr2line.1 ./prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9.1/bin/aarch64-linux-android-addr2line ./prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-addr2line ./prebuilts/gcc/linux-x86/arc/arc_gnu_2016.09_prebuilt_elf32_le_linux/bin/arc-elf32-addr2line ./prebuilts/gcc/linux-x86/arc/arc_gnu_2016.09_prebuilt_elf32_le_linux/share/man/man1/arc-elf32-addr2line.1 ./prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi-4_7-2012q4/bin/arm-none-eabi-addr2line ./prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9.1/bin/arm-linux-androideabi-addr2line ./prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-eabi/bin/arm-eabi-addr2line ./prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-eabi/share/doc/binutils.html/addr2line.html ./prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-eabi/share/man/man1/arm-eabi-addr2line.1 ./prebuilts/gcc/linux-x86/arm/gcc-linaro-7.1.1-2017.08-x86_64_arm-eabi/bin/arm-eabi-addr2line ./prebuilts/gcc/linux-x86/arm/gcc-linaro-7.1.1-2017.08-x86_64_arm-eabi/share/doc/binutils.html/addr2line.html ./prebuilts/gcc/linux-x86/arm/gcc-linaro-7.1.1-2017.08-x86_64_arm-eabi/share/man/man1/arm-eabi-addr2line.1 ./prebuilts/rust/darwin-x86/1.48.0/lib/rustlib/i686-linux-android/lib/libaddr2line-53d59ae352c562ca.rlib ./prebuilts/rust/darwin-x86/1.49.0/lib/rustlib/x86_64-linux-android/lib/libaddr2line-e67be5e2460aec9d.rlib ...... ......
At the same time, after source build/envsetup.sh and lunch in the Android source code, we enter the following commands and find that Android can supplement them for us:
ubuntu@ubuntu:/mnt/disk2/new$ arm-linux-androideabi- arm-linux-androideabi-addr2line arm-linux-androideabi-dwp arm-linux-androideabi-gcc-ar arm-linux-androideabi-ld arm-linux-androideabi-ranlib arm-linux-androideabi-ar arm-linux-androideabi-elfedit arm-linux-androideabi-gcc-nm arm-linux-androideabi-ld.bfd arm-linux-androideabi-readelf arm-linux-androideabi-as arm-linux-androideabi-g++ arm-linux-androideabi-gcc-ranlib arm-linux-androideabi-ld.gold arm-linux-androideabi-size arm-linux-androideabi-c++ arm-linux-androideabi-gcc arm-linux-androideabi-gcov arm-linux-androideabi-nm arm-linux-androideabi-strings arm-linux-androideabi-c++filt arm-linux-androideabi-gcc-4.9 arm-linux-androideabi-gcov-tool arm-linux-androideabi-objcopy arm-linux-androideabi-strip arm-linux-androideabi-cpp arm-linux-androideabi-gcc-4.9.x arm-linux-androideabi-gprof arm-linux-androideabi-objdump
Practical application:
Example from CSDN: https://blog.csdn.net/tkwxty/article/details/103493624
DALVIK THREADS (23): "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 obj=0x73698300 self=0xb73b40f0 | sysTid=20557 nice=0 cgrp=default sched=0/0 handle=0xb6f15bec | state=S schedstat=( 15160273605 193890933 2101 ) utm=1424 stm=92 core=0 HZ=100 | stack=0xbe2fb000-0xbe2fd000 stackSize=8MB | held mutexes= kernel: (couldn't read /proc/self/task/20557/stack) native: #00 pc 0000f9a8 /system/lib/libc.so (syscall+28) native: #01 pc 00013185 /system/lib/libc.so (_Z33__pthread_cond_timedwait_relativeP14pthread_cond_tP15pthread_mutex_tPK8timespec+56) native: #02 pc 0003b2e3 /system/lib/libhwui.so (???) native: #03 pc 0003b319 /system/lib/libhwui.so (???) native: #04 pc 00936c8b /data/dalvik-cache/arm/system@framework@boot.oat (Java_android_view_ThreadedRenderer_nSyncAndDrawFrame__JJJF+134)
Here we take #03 as an example for analysis. The specific steps are as follows:
(1) Find the libhwui.so file that has not been optimized. Of course, find it, as shown below
xxx$ find . -name libhwui.so ./out/target/product/msm8909/system/lib/libhwui.so ./out/target/product/msm8909/obj/SHARED_LIBRARIES/libhwui_intermediates/LINKED/libhwui.so ./out/target/product/msm8909/obj/lib/libhwui.so ./out/target/product/msm8909/symbols/system/lib/libhwui.so //This is what we want to use
(2) Found memory address "0003b319"
(3) Execute command
xxx$ arm-linux-androideabi-addr2line -f -e ./out/target/product/msm8909/symbols/system/lib/libhwui.so 0003b319 _ZN7android10uirenderer12renderthread13DrawFrameTask9drawFrameExx xxx/frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp:77
Case study on Dual Camera switching
Keywords where NE occurs: AEE_AED
09-20 07:37:29.801 5665 5665 I AEE_AED : handle_request(11) 09-20 07:37:29.802 5665 5665 I AEE_AED : pid: 797, tid: 5524, >>> /vendor/bin/hw/camerahalserver <<<
It can be seen that the camerahalserver has an ne. Generally, there is a reproduction problem. If an ne is generated, an exception folder, such as AEE, will be generated in the / data directory of the mobile phone_ Exp folder, which contains some db files, tombstones folder (which will record the type of NE and backtrace:), etc. with the help of debugging tools, we can better locate the problem.
If there is no db folder generation, you can try the following command:
adb root adb shell setenforce 0 adb shell setprop persist.vendor.mtk.aee.mode 3 adb shell setprop persist.vendor.mtk.aeev.mode 3 adb shell setprop persist.vendor.aeev.core.direct enable adb shell setprop persist.vendor.aeev.core.dump enable adb reboot
Use the command to grab the log and find the following fragments ():
09-24 14:25:23.469 26803 26803 I AEE_AED : pid: 17981, tid: 26672, name: N3DNode >>> /vendor/bin/hw/camerahalserver <<< 09-24 14:25:23.469 26803 26803 I AEE_AED : signal 11 (SIGSEGV), code --------, fault addr --------
You can see that signal 11 (SIGSEGV): is a null pointer. See the following log (aee_aed: stack start (7abe29b9c0), end (7abe29d963), length (1fa3)):
09-24 14:25:23.448 26803 26803 I AEE_AED : stack start(7abe29b9c0),end(7abe29d963),length(1fa3) 09-24 14:25:23.451 26803 26803 I AEE_AED : dump_stack64:dump stack ok 09-24 14:25:23.463 26803 26803 I AEE_AED : #00 pc 000000000004cdf8 /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy+248) (BuildId: e09b24987327c22afce455f46935acc6) 09-24 14:25:23.464 26803 26803 I AEE_AED : #01 pc 000000000003da40 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::__saveNVRAM()+160) (BuildId: ed08202e1c646e1e81a271952c52469e) 09-24 14:25:23.464 26803 26803 I AEE_AED : #02 pc 000000000003d7b0 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::~N3D_HAL_IMP()+1344) (BuildId: ed08202e1c646e1e81a271952c52469e) 09-24 14:25:23.464 26803 26803 I AEE_AED : #03 pc 000000000003dc48 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::~N3D_HAL_IMP()+16) (BuildId: ed08202e1c646e1e81a271952c52469e) 09-24 14:25:23.465 26803 26803 I AEE_AED : #04 pc 00000000000c3528 /vendor/lib64/libmtkcam.featurepipe.depthmap.so (NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::cleanUp()+400) (BuildId: fb069071692db5077ef6e67eb7b312a5) 09-24 14:25:23.465 26803 26803 I AEE_AED : #05 pc 00000000000c4368 /vendor/lib64/libmtkcam.featurepipe.depthmap.so (NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::onThreadStop()+272) (BuildId: fb069071692db5077ef6e67eb7b312a5) 09-24 14:25:23.466 26803 26803 I AEE_AED : #06 pc 00000000000c449c /vendor/lib64/libmtkcam.featurepipe.depthmap.so (non-virtual thunk to NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::onThreadStop()+12) (BuildId: fb069071692db5077ef6e67eb7b312a5) 09-24 14:25:23.467 26803 26803 I AEE_AED : #07 pc 00000000001f75a4 /vendor/lib64/libmtkcam.featurepipe.streaming.so (NSCam::NSCamFeature::NSFeaturePipe::CamThread::CamThreadHandle::threadLoop()+180) (BuildId: 5957950dd6e0bad9684a68f0c8002930) 09-24 14:25:23.467 26803 26803 I AEE_AED : #08 pc 0000000000012304 /apex/com.android.vndk.v31/lib64/libutils.so (android::Thread::_threadLoop(void*)+460) (BuildId: 5f04ee98c91df9e28e69d08a6224093d) 09-24 14:25:23.467 26803 26803 I AEE_AED : #09 pc 0000000000011acc /apex/com.android.vndk.v31/lib64/libutils.so thread_data_t::trampoline(thread_data_t const*)+404) (BuildId: 5f04ee98c91df9e28e69d08a6224093d) 09-24 14:25:23.467 26803 26803 I AEE_AED : #10 pc 00000000000b44e8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: e09b24987327c22afce455f46935acc6) 09-24 14:25:23.467 26803 26803 I AEE_AED : #11 pc 0000000000052848 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: e09b24987327c22afce455f46935acc6) 09-24 14:25:23.467 26803 26803 I AEE_AED : ne_direct_unwind end
Or backtrace
09-24 14:25:23.506 26803 26803 I AEE_AED : backtrace: 09-24 14:25:23.506 26803 26803 I AEE_AED : #00 pc 000000000004cdf8 /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy+248) 09-24 14:25:23.506 26803 26803 I AEE_AED : #01 pc 000000000003da40 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::__saveNVRAM()+160) 09-24 14:25:23.506 26803 26803 I AEE_AED : #02 pc 000000000003d7b0 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::~N3D_HAL_IMP()+1344) 09-24 14:25:23.506 26803 26803 I AEE_AED : #03 pc 000000000003dc48 /vendor/lib64/libfeature.vsdof.hal.so (N3D_HAL_IMP::~N3D_HAL_IMP()+16) 09-24 14:25:23.506 26803 26803 I AEE_AED : #04 pc 00000000000c3528 /vendor/lib64/libmtkcam.featurepipe.depthmap.so (NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::cleanUp()+400) 09-24 14:25:23.506 26803 26803 I AEE_AED : #05 pc 00000000000c4368 /vendor/lib64/libmtkcam.featurepipe.depthmap.so (NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::onThreadStop()+272) 09-24 14:25:23.506 26803 26803 I AEE_AED : #06 pc 00000000000c449c /vendor/lib64/libmtkcam.featurepipe.depthmap.so (non-virtual thunk to NSCam::NSCamFeature::NSFeaturePipe_DepthMap::N3DNode::onThreadStop()+12) 09-24 14:25:23.506 26803 26803 I AEE_AED : #07 pc 00000000001f75a4 /vendor/lib64/libmtkcam.featurepipe.streaming.so (NSCam::NSCamFeature::NSFeaturePipe::CamThread::CamThreadHandle::threadLoop()+180) 09-24 14:25:23.506 26803 26803 I AEE_AED : #08 pc 0000000000012304 /apex/com.android.vndk.v31/lib64/libutils.so (android::Thread::_threadLoop(void*)+460) 09-24 14:25:23.506 26803 26803 I AEE_AED : #09 pc 0000000000011acc /apex/com.android.vndk.v31/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+404) 09-24 14:25:23.506 26803 26803 I AEE_AED : #10 pc 00000000000b44e8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) 09-24 14:25:23.506 26803 26803 I AEE_AED : #11 pc 0000000000052848 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
As you can see, yes__ memcpy—>__ saveNVRAM()-—>~N3D_ HAL_ IMP()–>…… ……
Location code:
bool N3D_HAL_IMP::__saveNVRAM() { ...... ...... ::memcpy(__convAddr, __convergenceData, __CONV_SIZE);//Point of occurrence ...... ...... return bResult; } -----> N3D_HAL_IMP::~N3D_HAL_IMP() { ...... ...... } else if(__spPreviewKernel == &__n3dKernel) { __spPreviewKernel = NULL; __saveNVRAM(); ...... ...... MY_LOGD("%s -", (__eScenario == eSTEREO_SCENARIO_CAPTURE)?"Cap":"PV"); } <-----------------------------------------------
Print the log at memcpy and find__ convAddr is null, check__ The assignment logic of convAddr.
The key is to print out the stack information