Android超实用实战--分析汇编定位问题

引言

     本节,我们以一个简单的实例为引子,介绍一下汇编分析的一些技术知识,绝对超值实用,让我们对问题的认识更上一个档次!!

     我们的问题就是通过代码来模拟一个空指针,这种问题很常见,相信各位码农朋友在实际的工作中不知道碰到过多少次了。我们来看一下我们的实例,代码如下:

class CameraProcessor {
public:
    CameraProcessor();
    ~CameraProcessor();
    void testNull();
    int testReturn();

    Attrs *attrs = nullptr;
};
void CameraProcessor::testNull() {
    size_t type = offsetof(class Attrs, type);
    size_t enable = offsetof(class Attrs, enable);
    size_t mName = offsetof(class Attrs, mName);
    LOGE("%s, type=%zu, enable=%zu, mName=%zu.", __FUNCTION__, type, enable, mName);
    attrs->enable = true;
    attrs->mName = "CameraProcessor";
}
class Attrs {
public:
    Attrs();
    ~Attrs();
    int type;
    bool enable;
    std::string mName;
    std::condition_variable condition;
};

     我们定义了两个类,CameraProcessor和Attrs,Attrs作为CameraProcessor一个成员变量,声明时的值为空的,我们不对attrs成员变量作任何初始化,而在testNull方法中直接作用它,很显然,肯定会出现空指针。

     我们抓取到的空指针的日志如下:

10-30 13:22:30.980 28357 28357 E HongCameraJni: testNull, type=0, enable=4, mName=8.
--------- beginning of crash
10-30 13:22:30.980 28357 28357 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4 in tid 28357 (com.hong.camera), pid 28357 (com.hong.camera)
10-30 13:22:30.991 30323 30391 I RemoteGuardClient.DWB.ActivityMonitor: start game monitor packgeName = com.hong.camera
10-30 13:22:30.991 30323 30391 E RemoteGuardClient.DWB.ActivityMonitor: startGameAppMonitor failed! Failed resolution of: Lcom/oplus/remoteguardservice/GameIndulgeMonitorManager;
10-30 13:22:30.993 30323 30391 I RemoteGuardClient.DWB.ActivityMonitor: topActivities = [com.hong.camera]
10-30 13:22:31.003 30323 30391 I chatty  : uid=10160(com.coloros.remoteguardservice) appusage identical 7 lines
10-30 13:22:31.005 30323 30391 I RemoteGuardClient.DWB.ActivityMonitor: topActivities = [com.hong.camera]
10-30 13:22:31.049 28388 28388 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
10-30 13:22:31.052   768   768 I tombstoned: received crash request for pid 28357
10-30 13:22:31.053 28388 28388 I crash_dump64: performing dump of process 28357 (target tid = 28357)
10-30 13:22:31.058 28388 28388 F DEBUG   : Process name is com.hong.camera, not key_process
10-30 13:22:31.058 28388 28388 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-30 13:22:31.058 28388 28388 F DEBUG   : Build fingerprint: 'OPPO/PEGM00/OP4E8F:11/RKQ1.200903.002/1632393775226:user/release-keys'
10-30 13:22:31.058 28388 28388 F DEBUG   : Revision: '0'
10-30 13:22:31.058 28388 28388 F DEBUG   : ABI: 'arm64'
10-30 13:22:31.058 28388 28388 F DEBUG   : Timestamp: 2021-10-30 13:22:31+0800
10-30 13:22:31.058 28388 28388 F DEBUG   : pid: 28357, tid: 28357, name: com.hong.camera  >>> com.hong.camera <<<
10-30 13:22:31.058 28388 28388 F DEBUG   : uid: 10143
10-30 13:22:31.058 28388 28388 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
10-30 13:22:31.058 28388 28388 F DEBUG   : Cause: null pointer dereference
10-30 13:22:31.058 28388 28388 F DEBUG   :     x0  0000000000000001  x1  0000000000000000  x2  0000000000000050  x3  0000000000000003
10-30 13:22:31.058 28388 28388 F DEBUG   :     x4  0000007ffb34cf10  x5  0000000000000020  x6  0000006fd935d000  x7  000000000775cf88
10-30 13:22:31.058 28388 28388 F DEBUG   :     x8  b400006f4797b6e8  x9  0000000000000000  x10 0000000000000001  x11 0000000000000000
10-30 13:22:31.058 28388 28388 F DEBUG   :     x12 0000007ffb34d030  x13 0000000000000025  x14 0000007ffb34e378  x15 ffffffffffffffff
10-30 13:22:31.058 28388 28388 F DEBUG   :     x16 0000006fd4ef9740  x17 0000006fd66242e0  x18 0000006fd921e000  x19 b400006f51c10800
10-30 13:22:31.058 28388 28388 F DEBUG   :     x20 0000000000000000  x21 b400006f51c10800  x22 0000006fd81f1000  x23 b400006f51c108b8
10-30 13:22:31.058 28388 28388 F DEBUG   :     x24 0000006f475f9478  x25 0000006fd81f1000  x26 000000000000000b  x27 0000000000000001
10-30 13:22:31.058 28388 28388 F DEBUG   :     x28 0000007ffb34e8c0  x29 0000007ffb34e810
10-30 13:22:31.058 28388 28388 F DEBUG   :     lr  0000006ee3a51918  sp  0000007ffb34e7d0  pc  0000006ee3a51924  pst 0000000060001000
10-30 13:22:31.101  3357  3357 D OplusUIFirst: writeProcNode: /proc/sys/kernel/animation_type: open failed: EACCES (Permission denied)
10-30 13:22:31.102  1308  2613 W ORMS_CORE: Unknown request!!!
10-30 13:22:31.102  3357  3357 E Launcher.ColorBubbleTextView: mForceHideDot is false
10-30 13:22:31.103  1308  5873 V ColorZoomWindowManagerService: onAnimationFinished:  r = ActivityRecord{f2c21ac u0 com.oppo.launcher/.Launcher t2}
10-30 13:22:31.103  1308  5873 I OplusMirageDisplayManagerService: onAnimationFinished:
10-30 13:22:31.104  1308  5873 V ColorZoomWindowManagerService: onAnimationFinished:  r = ActivityRecord{934b0b2 u0 com.hong.camera/.MainActivity t14809}
10-30 13:22:31.104  1308  5873 I ColorAppSwitchManagerService:  handleAppVisible , r = ActivityRecord{934b0b2 u0 com.hong.camera/.MainActivity t14809}
10-30 13:22:31.104  1308  5873 I OplusMirageDisplayManagerService: onAnimationFinished:
10-30 13:22:31.116  1054  1054 E Layer   : [Surface(name=Task=2)/@0x6009a15 - animation-leash#0] No local sync point found
10-30 13:22:31.116  1054  1054 E Layer   : [Surface(name=Task=14809)/@0x9e4b363 - animation-leash#0] No local sync point found
10-30 13:22:31.129  1308  1665 D PowerManagerService: setScreenBrightnessOverrideFromWindowManagerInternal brightness=NaN mScreenBrightnessOverrideFromWindowManager=NaN
10-30 13:22:31.322 28388 28388 F DEBUG   : backtrace:
10-30 13:22:31.322 28388 28388 F DEBUG   :       #00 pc 000000000000f924  /data/app/~~NmChEb4A_LFPpSVoubGX6w==/com.hong.camera-cr78uXYrqqaBHnyKcFC4Cg==/base.apk!libcamera.so (offset 0x332000) (CameraProcessor::testNull()+124) (BuildId: 45fdad3a35dd940e928359775eced46a66c0b1e3)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #01 pc 000000000000eb98  /data/app/~~NmChEb4A_LFPpSVoubGX6w==/com.hong.camera-cr78uXYrqqaBHnyKcFC4Cg==/base.apk!libcamera.so (offset 0x332000) (Java_com_hong_camera_MainActivity_stringFromJNI+112) (BuildId: 45fdad3a35dd940e928359775eced46a66c0b1e3)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #02 pc 000000000013ced4  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #03 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #04 pc 00000000001a8a78  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #05 pc 0000000000318288  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #06 pc 000000000030e5b4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #07 pc 000000000067d050  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+848) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #08 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #09 pc 0000000000000398  [anon:dalvik-classes4.dex extracted in memory from /data/app/~~NmChEb4A_LFPpSVoubGX6w==/com.hong.camera-cr78uXYrqqaBHnyKcFC4Cg==/base.apk!classes4.dex] (com.hong.camera.MainActivity.onCreate+48)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #10 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #11 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #12 pc 00000000001cdd68  /system/framework/framework.jar (android.app.Activity.performCreate+88)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #13 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #14 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #15 pc 00000000001cdcf6  /system/framework/framework.jar (android.app.Activity.performCreate+2)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #16 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #17 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #18 pc 0000000000239376  /system/framework/framework.jar (android.app.Instrumentation.callActivityOnCreate+6)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #19 pc 0000000000305bb0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+268) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #20 pc 000000000030dba0  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #21 pc 000000000030ef88  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+1772) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #22 pc 0000000000174fb8  /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+45680) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #23 pc 000000000013f7d8  /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #24 pc 00000000001bae1c  /system/framework/framework.jar (android.app.ActivityThread.performLaunchActivity)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #25 pc 0000000000305cb8  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+532) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #26 pc 000000000030dba0  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #27 pc 000000000030ef88  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+1772) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #28 pc 0000000000174fb8  /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+45680) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #29 pc 000000000013f7d8  /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #30 pc 00000000001bacac  /system/framework/framework.jar (android.app.ActivityThread.handleLaunchActivity)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #31 pc 0000000000305cb8  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+532) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #32 pc 000000000030dba0  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #33 pc 000000000030e598  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+968) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #34 pc 000000000067d050  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+848) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #35 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #36 pc 00000000002c268e  /system/framework/framework.jar (android.app.servertransaction.LaunchActivityItem.execute+134)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #37 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #38 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #39 pc 00000000002c4a7e  /system/framework/framework.jar (android.app.servertransaction.TransactionExecutor.executeCallbacks+286)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #40 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #41 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #42 pc 00000000002c4900  /system/framework/framework.jar (android.app.servertransaction.TransactionExecutor.execute+228)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #43 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #44 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #45 pc 00000000001b9f94  /system/framework/framework.jar (android.app.ActivityThread$H.handleMessage+292)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #46 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #47 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #48 pc 00000000003d0a7a  /system/framework/framework.jar (offset 0x97a000) (android.os.Handler.dispatchMessage+38)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #49 pc 000000000067d2f0  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1520) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #50 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #51 pc 00000000004032d4  /system/framework/framework.jar (offset 0x97a000) (android.os.Looper.loop+704)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #52 pc 0000000000305bb0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+268) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #53 pc 000000000030dba0  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #54 pc 000000000030ef88  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+1772) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #55 pc 0000000000177f40  /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+57848) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #56 pc 000000000013f7d8  /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #57 pc 00000000001c56d4  /system/framework/framework.jar (android.app.ActivityThread.main)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #58 pc 0000000000305cb8  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+532) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #59 pc 000000000066bd68  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #60 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #61 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #62 pc 00000000001a8a94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #63 pc 00000000005562a8  /apex/com.android.art/lib64/libart.so (art::InvokeMethod(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1364) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #64 pc 00000000004d53c0  /apex/com.android.art/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+52) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #65 pc 00000000000947f4  /apex/com.android.art/javalib/arm64/boot.oat (art_jni_trampoline+180) (BuildId: edd3d6f9e9815a243df4398468ae6aff6f504f57)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #66 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #67 pc 00000000001a8a78  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #68 pc 0000000000318288  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #69 pc 000000000030e5b4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #70 pc 000000000067d050  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+848) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #71 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #72 pc 000000000052861e  /system/framework/framework.jar (offset 0x12ae000) (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+22)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #73 pc 0000000000305bb0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.10703641466876112822)+268) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #74 pc 000000000066bd68  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #75 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #76 pc 00000000008fb804  /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteInit.main+2756) (BuildId: 032cf8321414e036ac8148927261555bff1160bf)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #77 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #78 pc 00000000001a8a94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #79 pc 0000000000554ce4  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #80 pc 0000000000555198  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #81 pc 0000000000438fc8  /apex/com.android.art/lib64/libart.so (art::JNI<true>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+656) (BuildId: dbcc3c3d5c0c8df4b9c89d440fd3cb23)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #82 pc 000000000009c424  /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+124) (BuildId: 61bc130b4f0706c2cfdde48dae6bc2fb)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #83 pc 00000000000a4160  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+856) (BuildId: 61bc130b4f0706c2cfdde48dae6bc2fb)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #84 pc 0000000000003674  /system/bin/app_process64 (main+1580) (BuildId: 9349370b830e2b77b835dee3aff71480)
10-30 13:22:31.323 28388 28388 F DEBUG   :       #85 pc 0000000000073a5c  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108) (BuildId: 1ca28d785d6567d2b225cf978ef04de5)

     我们上面日志中第一行对应的就是我们testNull方法中的日志,我们是为了获取每一个成员变量相对CameraProcessor class的偏移量,这个值后续会用到。

一、确定问题的直接原因

     我在自己的工作中经常提问题的直接原因和根本原因,就是为了区别这两个概念,直接原因就是直接导致问题出现的原因,比如在我们的日常工作中,经常会有踩内存的问题出现,这时候直接原因就是被踩的内存内容已经异常了,使用的时候必然导致崩溃或一些不可预知的逻辑行为;但是根因原因就要查它是被谁踩了,为什么被踩了,踩了多大等等,查到根本原因,才能真正的把问题解决掉,相信大家肯定都有这样的认识。

     我们在工作中也经常碰到空指针问题,有时候是多线程竞争导致的,这时候的直接原因就是被调用的对象空指针,必然导致崩溃,而根本原因我们就必须去查它为什么为空了,这时候为空肯定是一些边界条件出现的,因为我们的程序大部分正常情况是没有问题的。查到根本原因,我们才可能彻底解决问题,如果我们只是单纯针对变量判空,那就是没有用的,问题肯定还会继续出现。

     回来我们本例中,首先来确定一下问题的直接原因,从下面的日志中我们可以直接确定出当前崩溃的直接原因就是空指针。

10-30 13:22:31.058 28388 28388 F DEBUG   : Process name is com.hong.camera, not key_process
10-30 13:22:31.058 28388 28388 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-30 13:22:31.058 28388 28388 F DEBUG   : Build fingerprint: 'OPPO/PEGM00/OP4E8F:11/RKQ1.200903.002/1632393775226:user/release-keys'
10-30 13:22:31.058 28388 28388 F DEBUG   : Revision: '0'
10-30 13:22:31.058 28388 28388 F DEBUG   : ABI: 'arm64'
10-30 13:22:31.058 28388 28388 F DEBUG   : Timestamp: 2021-10-30 13:22:31+0800
10-30 13:22:31.058 28388 28388 F DEBUG   : pid: 28357, tid: 28357, name: com.hong.camera  >>> com.hong.camera <<<
10-30 13:22:31.058 28388 28388 F DEBUG   : uid: 10143
10-30 13:22:31.058 28388 28388 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
10-30 13:22:31.058 28388 28388 F DEBUG   : Cause: null pointer dereference
10-30 13:22:31.058 28388 28388 F DEBUG   :     x0  0000000000000001  x1  0000000000000000  x2  0000000000000050  x3  0000000000000003
10-30 13:22:31.058 28388 28388 F DEBUG   :     x4  0000007ffb34cf10  x5  0000000000000020  x6  0000006fd935d000  x7  000000000775cf88
10-30 13:22:31.058 28388 28388 F DEBUG   :     x8  b400006f4797b6e8  x9  0000000000000000  x10 0000000000000001  x11 0000000000000000
10-30 13:22:31.058 28388 28388 F DEBUG   :     x12 0000007ffb34d030  x13 0000000000000025  x14 0000007ffb34e378  x15 ffffffffffffffff
10-30 13:22:31.058 28388 28388 F DEBUG   :     x16 0000006fd4ef9740  x17 0000006fd66242e0  x18 0000006fd921e000  x19 b400006f51c10800
10-30 13:22:31.058 28388 28388 F DEBUG   :     x20 0000000000000000  x21 b400006f51c10800  x22 0000006fd81f1000  x23 b400006f51c108b8
10-30 13:22:31.058 28388 28388 F DEBUG   :     x24 0000006f475f9478  x25 0000006fd81f1000  x26 000000000000000b  x27 0000000000000001
10-30 13:22:31.058 28388 28388 F DEBUG   :     x28 0000007ffb34e8c0  x29 0000007ffb34e810
10-30 13:22:31.058 28388 28388 F DEBUG   :     lr  0000006ee3a51918  sp  0000007ffb34e7d0  pc  0000006ee3a51924  pst 0000000060001000

     日志中还有一些其他信息:崩溃进程的名称为>>> com.hong.camera <<<;崩溃进程的进程id为pid: 28357,发生崩溃的线程id为tid: 28357;发生问题的时间点为Timestamp: 2021-10-30 13:22:31+0800;当前崩溃进程的abi是64位进程ABI: 'arm64';当前进程的uid信息uid: 10143;导致崩溃的signal信号为signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4,0x4是导致崩溃的非法地址值;Cause信息为Cause: null pointer dereference;紧接着下面还有发生崩溃时的寄存器和堆栈信息,这些信息非常简明而且重要。

二、objdump准备好so库反汇编

     这一步比较简单,llvm-objdump  -d  libcamera.so  > libcamera.txt,现成的命令直接执行一下,把反汇编的结果保存到文件中,方便分析,我就从结果中截取一段如下:

000000000000eb28 <Java_com_hong_camera_MainActivity_stringFromJNI>:
    eb28: ff 03 02 d1  	sub	sp, sp, #128
    eb2c: fd 7b 07 a9  	stp	x29, x30, [sp, #112]
    eb30: fd c3 01 91  	add	x29, sp, #112
    eb34: 48 d0 3b d5  	mrs	x8, TPIDR_EL0
    eb38: 08 15 40 f9  	ldr	x8, [x8, #40]
    eb3c: a8 83 1f f8  	stur	x8, [x29, #-8]
    eb40: a0 83 1d f8  	stur	x0, [x29, #-40]
    eb44: a1 03 1d f8  	stur	x1, [x29, #-48]
    eb48: c1 00 00 d0  	adrp	x1, 0x28000 <Java_com_hong_camera_MainActivity_stringFromJNI+0x88>
    eb4c: 21 40 22 91  	add	x1, x1, #2192
    eb50: a0 83 00 d1  	sub	x0, x29, #32
    eb54: 93 ff ff 97  	bl	0xe9a0 <$x+0x440>
    eb58: 09 01 80 52  	mov	w9, #8
    eb5c: e0 03 09 2a  	mov	w0, w9
    eb60: c0 fe ff 97  	bl	0xe660 <$x+0x100>
    eb64: e0 17 00 f9  	str	x0, [sp, #40]
    eb68: 01 00 00 14  	b	0xeb6c <Java_com_hong_camera_MainActivity_stringFromJNI+0x44>
    eb6c: e0 17 40 f9  	ldr	x0, [sp, #40]
    eb70: e1 17 40 f9  	ldr	x1, [sp, #40]
    eb74: e0 13 00 f9  	str	x0, [sp, #32]
    eb78: e0 03 01 aa  	mov	x0, x1
    eb7c: fd fe ff 97  	bl	0xe770 <$x+0x210>
    eb80: 01 00 00 14  	b	0xeb84 <Java_com_hong_camera_MainActivity_stringFromJNI+0x5c>
    eb84: 28 01 00 d0  	adrp	x8, 0x34000 <Java_com_hong_camera_MainActivity_stringFromJNI+0xf4>
    eb88: 08 dd 47 f9  	ldr	x8, [x8, #4024]
    eb8c: e9 13 40 f9  	ldr	x9, [sp, #32]
    eb90: 09 01 00 f9  	str	x9, [x8]
    eb94: 00 01 40 f9  	ldr	x0, [x8]
    eb98: be fe ff 97  	bl	0xe690 <$x+0x130>
    eb9c: 01 00 00 14  	b	0xeba0 <Java_com_hong_camera_MainActivity_stringFromJNI+0x78>
    eba0: a0 83 5d f8  	ldur	x0, [x29, #-40]
    eba4: a8 83 00 d1  	sub	x8, x29, #32
    eba8: e0 0f 00 f9  	str	x0, [sp, #24]
    ebac: e0 03 08 aa  	mov	x0, x8
    ebb0: 46 00 00 94  	bl	0xecc8 <_ZNKSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv>
    ebb4: e8 0f 40 f9  	ldr	x8, [sp, #24]
    ebb8: e0 0b 00 f9  	str	x0, [sp, #16]
    ebbc: e0 03 08 aa  	mov	x0, x8
    ebc0: e1 0b 40 f9  	ldr	x1, [sp, #16]
    ebc4: bb fe ff 97  	bl	0xe6b0 <$x+0x150>
    ebc8: e0 07 00 f9  	str	x0, [sp, #8]
    ebcc: 01 00 00 14  	b	0xebd0 <Java_com_hong_camera_MainActivity_stringFromJNI+0xa8>
    ebd0: a0 83 00 d1  	sub	x0, x29, #32
    ebd4: 07 ff ff 97  	bl	0xe7f0 <$x+0x290>
    ebd8: 48 d0 3b d5  	mrs	x8, TPIDR_EL0
    ebdc: 08 15 40 f9  	ldr	x8, [x8, #40]
    ebe0: a9 83 5f f8  	ldur	x9, [x29, #-8]
    ebe4: 08 01 09 eb  	subs	x8, x8, x9
    ebe8: 61 02 00 54  	b.ne	0xec34 <Java_com_hong_camera_MainActivity_stringFromJNI+0x10c>
    ebec: 01 00 00 14  	b	0xebf0 <Java_com_hong_camera_MainActivity_stringFromJNI+0xc8>
    ebf0: e0 07 40 f9  	ldr	x0, [sp, #8]
    ebf4: fd 7b 47 a9  	ldp	x29, x30, [sp, #112]
    ebf8: ff 03 02 91  	add	sp, sp, #128
    ebfc: c0 03 5f d6  	ret
    ec00: e0 1f 00 f9  	str	x0, [sp, #56]
    ec04: e1 37 00 b9  	str	w1, [sp, #52]
    ec08: 06 00 00 14  	b	0xec20 <Java_com_hong_camera_MainActivity_stringFromJNI+0xf8>
    ec0c: e0 1f 00 f9  	str	x0, [sp, #56]
    ec10: e1 37 00 b9  	str	w1, [sp, #52]
    ec14: e0 17 40 f9  	ldr	x0, [sp, #40]
    ec18: 4a ff ff 97  	bl	0xe940 <$x+0x3e0>
    ec1c: 01 00 00 14  	b	0xec20 <Java_com_hong_camera_MainActivity_stringFromJNI+0xf8>
    ec20: a0 83 00 d1  	sub	x0, x29, #32
    ec24: f3 fe ff 97  	bl	0xe7f0 <$x+0x290>
    ec28: 01 00 00 14  	b	0xec2c <Java_com_hong_camera_MainActivity_stringFromJNI+0x104>
    ec2c: e0 1f 40 f9  	ldr	x0, [sp, #56]
    ec30: 45 60 00 94  	bl	0x26d44 <_Unwind_Resume>
    ec34: eb fe ff 97  	bl	0xe7e0 <$x+0x280>
000000000000f8a8 <_ZN15CameraProcessor8testNullEv>:
    f8a8: ff 43 01 d1  	sub	sp, sp, #80
    f8ac: fd 7b 04 a9  	stp	x29, x30, [sp, #64]
    f8b0: fd 03 01 91  	add	x29, sp, #64
    f8b4: 88 00 80 d2  	mov	x8, #4
    f8b8: 09 01 80 d2  	mov	x9, #8
    f8bc: ca 00 80 52  	mov	w10, #6
    f8c0: c1 00 00 b0  	adrp	x1, 0x28000 <_ZN15CameraProcessor8testNullEv+0x7c>
    f8c4: 21 8c 23 91  	add	x1, x1, #2275
    f8c8: c2 00 00 b0  	adrp	x2, 0x28000 <_ZN15CameraProcessor8testNullEv+0x84>
    f8cc: 42 c4 23 91  	add	x2, x2, #2289
    f8d0: c3 00 00 b0  	adrp	x3, 0x28000 <_ZN15CameraProcessor8testNullEv+0x8c>
    f8d4: 63 58 24 91  	add	x3, x3, #2326
    f8d8: 2b 00 80 52  	mov	w11, #1
    f8dc: cc 00 00 b0  	adrp	x12, 0x28000 <_ZN15CameraProcessor8testNullEv+0x98>
    f8e0: 8c 7d 24 91  	add	x12, x12, #2335
    f8e4: a0 83 1f f8  	stur	x0, [x29, #-8]
    f8e8: ad 83 5f f8  	ldur	x13, [x29, #-8]
    f8ec: bf 03 1f f8  	stur	xzr, [x29, #-16]
    f8f0: a8 83 1e f8  	stur	x8, [x29, #-24]
    f8f4: e9 13 00 f9  	str	x9, [sp, #32]
    f8f8: a4 03 5f f8  	ldur	x4, [x29, #-16]
    f8fc: a5 83 5e f8  	ldur	x5, [x29, #-24]
    f900: e6 13 40 f9  	ldr	x6, [sp, #32]
    f904: e0 03 0a 2a  	mov	w0, w10
    f908: eb 1f 00 b9  	str	w11, [sp, #28]
    f90c: ec 0b 00 f9  	str	x12, [sp, #16]
    f910: ed 07 00 f9  	str	x13, [sp, #8]
    f914: cb fb ff 97  	bl	0xe840 <$x+0x2e0>
    f918: e8 07 40 f9  	ldr	x8, [sp, #8]
    f91c: 09 01 40 f9  	ldr	x9, [x8]
    f920: ea 1f 40 b9  	ldr	w10, [sp, #28]
    f924: 2a 11 00 39  	strb	w10, [x9, #4]
    f928: 09 01 40 f9  	ldr	x9, [x8]
    f92c: 0c 01 80 d2  	mov	x12, #8
    f930: 29 01 0c 8b  	add	x9, x9, x12
    f934: e0 03 09 aa  	mov	x0, x9
    f938: e1 0b 40 f9  	ldr	x1, [sp, #16]
    f93c: 04 00 00 94  	bl	0xf94c <_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEPKc>
    f940: fd 7b 44 a9  	ldp	x29, x30, [sp, #64]
    f944: ff 43 01 91  	add	sp, sp, #80
    f948: c0 03 5f d6  	ret

三、分析崩溃堆栈

     出现native crash时,请大家要有这样的意识,第一着眼点就是crash堆栈,它指示着我们的代码执行的调用关系,是非常直接的有效信息。我们来看一下当前的问题。

     把跟我们libcamera.so库相关的堆栈提取出来,日志如下:

10-30 13:22:31.322 28388 28388 F DEBUG   :       #00 pc 000000000000f924  /data/app/~~NmChEb4A_LFPpSVoubGX6w==/com.hong.camera-cr78uXYrqqaBHnyKcFC4Cg==/base.apk!libcamera.so (offset 0x332000) (CameraProcessor::testNull()+124) (BuildId: 45fdad3a35dd940e928359775eced46a66c0b1e3)
10-30 13:22:31.322 28388 28388 F DEBUG   :       #01 pc 000000000000eb98  /data/app/~~NmChEb4A_LFPpSVoubGX6w==/com.hong.camera-cr78uXYrqqaBHnyKcFC4Cg==/base.apk!libcamera.so (offset 0x332000) (Java_com_hong_camera_MainActivity_stringFromJNI+112) (BuildId: 45fdad3a35dd940e928359775eced46a66c0b1e3)

     我们可以使用addr2line命令来定位代码行信息:llvm-addr2line   -C -f -e libcamera.so   000000000000eb98,结果显示如下,不过在实际的工作中有碰到有时候定位到的代码行不准确的问题,所以这里的行号只能作为参考。

     我们先来看#00栈帧,偏移量为000000000000f924,我们可以直接在so库反汇编的结果中搜索f924,一共两处,一处是1f924,明显不符合, 另一处,就是我们上面so库反汇编结果中贴的第二段代码片了,我们可以看到该代码片就是CameraProcessor::testNull()方法的汇编代码了。

     再来看一下f924,截取片段如下:

    f910: ed 07 00 f9  	str	x13, [sp, #8]
    f914: cb fb ff 97  	bl	0xe840 <$x+0x2e0>
    f918: e8 07 40 f9  	ldr	x8, [sp, #8]
    f91c: 09 01 40 f9  	ldr	x9, [x8]
    f920: ea 1f 40 b9  	ldr	w10, [sp, #28]
    f924: 2a 11 00 39  	strb	w10, [x9, #4]

     它所要执行的汇编指令为strb    w10, [x9, #4],具体的意思是把x10寄存器的低32位字节数据存储到以x9 + 4为地址的存储器中,这里有中括号表示间接寻址,也就是x9寄存器的地址加上4得到的一个有效地址,把内容写到这个地址对应的存储器中,这里需要正确理解它的意思。

     这句汇编为什么崩溃呢?是x10寄存器非法还是x9寄存器非法?我们看一下崩溃时的寄存器信息,x10寄存器中的值为0000000000000001,x9寄存器的值为0000000000000000,崩溃的地址0x4也就是这行汇编指令x9 + 4得到的了,我们的进程是64位进程,一个合法有效的指针地址是10位,比如x17 0000006fd66242e0、x18 0000006fd921e000,而现在要往0x4这个地址写入数据,肯定会崩溃了。

     再来看一下x10寄存器的值为什么是0000000000000001,结合我们的代码:

attrs->enable = true;
LOGE("%s, type=%zu, enable=%zu, mName=%zu.", __FUNCTION__, type, enable, mName);

10-30 13:22:30.980 28357 28357 E HongCameraJni: testNull, type=0, enable=4, mName=8.

     我们可以直接推断,x9寄存器存储的就是attrs成员变量的指针地址,enable的偏移量我们在日志中已经打印出来了,就是4,所以和崩溃时的汇编也就正好对应上了,这行代码的右值true也就是1,存储在x10寄存器中,把它赋值给存储attrs成员变量的x9寄存器偏移4得到的enable成员变量。

     看到这,大家对我们的代码是不是有了更加深刻的认识?

     我们用高级语言写的一行代码,在汇编中可能就分成很多行了,寄存器中存储对应的指针地址或者立即数,然后进行各种操作,交给cpu执行,我们的程序在cpu上就是这样运行的!!

     调用堆栈中的其他栈帧也是在崩溃信息中的偏移量处依次调用下一帧,连起来就成了我们看到的日志信息了。

四、确定根因

     从第三小节的分析中,我们其实已经确定根因了,就是执行attrs->enable = true逻辑时,左值attrs为空导致崩溃的,因为我们的例子很简单,而实际工作中,情况要复杂的多,但是处理问题的思路是完全相同的,掌握了方法,处理实际的问题时,就会更有力一些。

     再次声明一下,有些同学看完可能会问,就是一个很简单的空指针,绕了这么一大堆,有这个必要吗?不用后边的分析,一开始就能得到!

     这是因为我们的例子简单,实际情况肯定比较复杂,我们学习掌握这些汇编分析手段,能让我们定位问题的手段更丰富,相信有很多问题都不会像我们这个例子这样简单,通过分析汇编,我们能更加清晰的认识到问题的本质,另外公司内部有大神分析汇编解决问题的博客,拿出来绝对让大家竖五十个大拇指佩服,定位的非常清晰,真是把问题的祖宗十八代都挖出来了,我们要达到的就是那样的境界,如果只是在c++层逛,那毛用都没得!

五、修改方案

     分析到了问题的根因,剩下的就是针对根因制定修改方案了,本例的bug我们就不展开了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红-旺永福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值