引言
本节,我们以一个简单的实例为引子,介绍一下汇编分析的一些技术知识,绝对超值实用,让我们对问题的认识更上一个档次!!
我们的问题就是通过代码来模拟一个空指针,这种问题很常见,相信各位码农朋友在实际的工作中不知道碰到过多少次了。我们来看一下我们的实例,代码如下:
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我们就不展开了。