任何系統,硬件故障和軟件故障都不可避免。比如車載系統,由於汽車行駛過程中的震動,發熱等,很容易影響電子元件的特性,發生電容的0和1狀態的切換。這對程序是致命的影響,會直接改變程序邏輯及運行結果。這種情況稱之為位反轉(Bit Flip)。
這種對安全要求高的場景,編程時需要對變量進行保護。常見方法是鏡像法,即在兩個不同的地方寫入同一個變量,讀取時對2個變量的值進行校驗。如果結果不一致,就要進行容錯處理。
1、什么是bitflip?
cpu中(cache或寄存器)或DDR中或flash中的 一個或者多個bit發生位反轉如0變為1,1變為0.這樣的變化沒有軟件參與,是硬件自己變的!!
2、為什么會發生bitflip?
- 器件不良-----比如cpu ddr flash 本身就有質量缺陷
- 器件供電不足或者供電受到干擾-----cpu ddr flash的穩定工作需要一定的電壓頻率,如果供電不足或者波動較大 那么其內部狀態會不穩定從而引起bitflip
- 傳輸干擾-----數據在cpu-ddr或ddr-flash間流動時如果引腳干擾大也會導致傳輸出錯(不過一般有傳輸校驗這種 情況幾率較小)
- 引腳虛焊-----器件與主板的硬件有虛焊當然會有問題
- 主板損壞或微損壞------導致送給器件的電或者信號不穩定
以上 除器件不良外都屬於器件的供電或者其它信號會受到干擾或者不穩定的情況-----一般與主板強相關
下面直接以一個例子來分析。
pid: 481, tid: 13908, name: HwBinder:481_5 >>> /system/bin/cameraserver <<<
signal 4 (SIGILL), code --------, fault addr --------
r0 00000280 r1 000001e0 r2 ed6ff410 r3 00000000
r4 c69d2668 r5 ef0b7800 r6 00000003 r7 00003f23
r8 00000000 r9 ffffffff sl ef0b7ed0 fp ef2313c8
ip eea7bcc0 sp ed6ff3d0 lr f0019c4f pc f0019c92 cpsr 60000030
對應的調用堆棧如下:
#00 pc 00059c92 /system/lib/libgui.so (android::Surface::queueBuffer(ANativeWindowBuffer*, int)+249)
#01 pc 000a5865 /system/lib/libcameraservice.so (android::CameraHardwareInterface::enqueueBuffer(unsigned long long)+56)
#02 pc 000a5921 /system/lib/libcameraservice.so (_ZTv0_n68_N7android23CameraHardwareInterface13enqueueBufferEy+12)
#03 pc 000316ad /system/lib/android.hardware.camera.device@1.0.so
發生該種NE SIGILL,表示pc執行了非法指令,它的產生原因一般為如下幾種:
<1>執行的文件本身出現問題,文件本身出錯了
<2>執行了數據段中的內容
<3>堆棧被踩壞或溢出,導致執行了非法指令
<4>發生了bitflip導致指令跳轉到非法地址
對於<1>可以對比coredump文件和libgui.so反匯編之后的匯編代碼,確認是否一致,如果一致,說明so文件本身沒有問題。
(gdb) x /8xh 0xf0019c8e
0xf0019c8e <android::Surface::queueBuffer(ANativeWindowBuffer*, int)+246>: 0xe9db 0x0108 0xf10d 0x0bb0 0xe9cd 0x332c 0xe9cd 0x012e
(gdb)通過gdb來看coredump中地址0xf0019c92附件的指令編碼,從0xf0019c92- 0xf0019c95地址對應的編碼為0xf10d 0x0bb0,
這個與libgui.so中偏移地址00059c92對應的編碼是一樣的,如下所示:
59c8e: e9db 0108 ldrd r0, r1, [fp, #32]
59c92: f10d 0bb0 add.w fp, sp, #176 ; 0xb0
因此,如果coredump中讀取的內容與libgui.so中的編碼是一樣,那么說明不是文件本身出問題。
<2>執行了數據段的內容,這個可以根據pc地址以及結合maps中的虛擬地址范圍來確定
<3>堆棧是否被踩壞,需要coredump打印堆棧中的內容以及結合前一幀堆棧內容來推導堆棧內容是否有異常,一般需要結合匯編代碼來分析。
<4> bitflip是否跳轉確認
[69422.917814] (1)[13908:HwBinder:481_5]HwBinder:481_5[13908]: undefined instruction: pc=00000000f0019c92
[69422.917848] (1)[13908:HwBinder:481_5]Code: aa100a8f b00cf8cd 0acff942 0108e9db (0bb0f90d)
上面語句表示pc地址00000000f0019c92對應的編碼為0bb0f90d,也就是括號中的值,編碼包括操作碼和操作數,
括號前面的幾個編碼aa100a8f b00cf8cd 0acff942 0108e9db,它表示pc地址之前的幾個地址對應的指令編碼。
(gdb) p /x *0xf0019c92 從coredump信息可以看出0xf0019c92對應的指令編碼為0xbb0f10d,
$12 = 0xbb0f10d //這個是正常的指令編碼
對比0xbb0f10d與0bb0f90d,確實有一個 bit發生了跳轉,0xbb0f10d 這個是正常的指令編碼,但真正執行時卻變為0bb0f90d,因此是硬件bit位發生了跳轉導致NE,屬於硬件問題。
對於bitflip一般需要做硬件交叉實驗來進一步確認問題。