1情景
售后 : X工,現(xiàn)場出大事了,今天升級的程序跑著跑著就掛了!現(xiàn)在整個產(chǎn)線都等著這個設(shè)備恢復(fù),能安排個人過來支援下嗎?
bug菌 : my god !別慌,我問一下負(fù)責(zé)的A工。
bug菌 : 喂,A工,昨天升級的程序有問題,程序卡死,售后在現(xiàn)場你聯(lián)系一下,支援他一波,順便把程序發(fā)送給我一份,一起看看!
A工 : 啊,還有這種事,程序沒改什么呀,行,我跟售后聯(lián)系一下。
經(jīng)過一番折騰,發(fā)現(xiàn)由于程序測試不到位,導(dǎo)致了一個強(qiáng)制類型轉(zhuǎn)化引發(fā)的進(jìn)入異常,這里就分享給大家。
2bug演示
這是一個老項目,采用stm32F4芯片為主控,由于硬件限制而客戶又不愿意花大價錢改造,所以程序架構(gòu)等等都沒有再大動作,由于通信上的傳輸和解析都是字節(jié)流,一些小的需求都只是在原來的通信架構(gòu)上把4個字節(jié)拆成2個字節(jié)來用,然而這一次實在沒辦法沒改接收數(shù)據(jù)類型,然后把一個double類型拆成了4個uint16來使用,沒想到出問題了。
所以這里簡單的模擬演示了一下:
A工用一個double類型取地址,然后把地址強(qiáng)制轉(zhuǎn)為uint64_t類型,以此類型指針取內(nèi)容,當(dāng)這段代碼執(zhí)行完程序就跳到了異常中斷,導(dǎo)致死機(jī)。
其實這段代碼對于經(jīng)驗豐富的人來說,一看就覺得很變扭,但是無論如何也不至于死機(jī)呀,畢竟強(qiáng)制類型轉(zhuǎn)化大部分人拿來都是隨便用。
3bug解讀
當(dāng)看到A工寫的這一套代碼,bug菌其實隱隱約約就感覺這塊有些問題,但是沒敢確定,畢竟整套代碼也是前人留下的,全是邏輯沒什么精華也沒有過細(xì)研究,最后看這段代碼的匯編才知道問題所在。
在之前bug菌也曾比較詳細(xì)的出過一篇分析此類問題的文章,可能這一塊并沒有吸引到你,不過還是一句話:"出來混都是要還的!"。
其實問題就出在LDRD這個ARM匯編指令上,LDRD指令表示從指定內(nèi)存地址取double word,上面圖片代碼中的LDRD R0,R1,[R2,#0x2EC],可以分解為下面兩個ldr步驟 :
在ARM匯編指令集中LDRD和STRD是一對加載和提取指令,一般都需要使用__align(8)修飾來保證數(shù)據(jù)對象進(jìn)行8直接對齊,而使用#pragma pack(8)是來指定結(jié)構(gòu)體成員變量相對于第一個變量的地址的偏移量的對齊方式。
__align指示編譯器在 n 字節(jié)邊界上對齊變量,是一個存儲類修飾符,當(dāng)然也可以以讓2字節(jié)的對象進(jìn)行4字節(jié)對齊其與8字節(jié)對齊是等價的,一定要記得是存儲的起始地址為8的整數(shù)倍。
對齊可以在一定程度上提高數(shù)據(jù)提取的效率,一旦起始地址沒有對齊會導(dǎo)致對齊錯誤,所以上面的double浮點類型的結(jié)構(gòu)體變量沒有8字節(jié)地址對齊,當(dāng)進(jìn)行強(qiáng)制類型轉(zhuǎn)化并使用LDRD指令就導(dǎo)致未對齊故障。
3更專業(yè)點
當(dāng)然對于跳轉(zhuǎn)到硬件異常的故障是非常好排查的,下面這篇文章教你如何迅速的定位故障位置和故障信息 :
對于非對齊指令的執(zhí)行會導(dǎo)致指令用法上的故障,那么Cortex芯片中相應(yīng)的故障寄存器標(biāo)志位會置位。
以上來自于Cortex技術(shù)文檔,文檔中也寫得非常的詳細(xì)。
當(dāng)CPU嘗試做一個未對齊的內(nèi)存訪問,然后就會發(fā)生此錯誤。特別是對于未對齊的LDM/STM/LDRD/STRD指令,所以進(jìn)入異常中斷以后查詢芯片內(nèi)部故障寄存器也是可以找到問題所在的,對于使用仿真器排查是再簡單不過了,如果是離線排查就需要進(jìn)行上篇文章那樣打印相關(guān)日志來定位問題。
本文來源:公眾號:最后一個bug
審核編輯:湯梓紅
-
STM32
+關(guān)注
關(guān)注
2290文章
11017瀏覽量
362466 -
代碼
+關(guān)注
關(guān)注
30文章
4887瀏覽量
70271 -
BUG
+關(guān)注
關(guān)注
0文章
156瀏覽量
15962
原文標(biāo)題:stm32一個強(qiáng)制類型轉(zhuǎn)換死機(jī),讓我付出了慘痛的代價~
文章出處:【微信號:嵌入式情報局,微信公眾號:嵌入式情報局】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
TCP中強(qiáng)制類型轉(zhuǎn)換
laview中強(qiáng)制類型轉(zhuǎn)換控件使用的一些心得
強(qiáng)制類型轉(zhuǎn)換問題
一個奇怪的現(xiàn)象,增加結(jié)構(gòu)節(jié)點后,影響強(qiáng)制類型轉(zhuǎn)換的速度
請問使用強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換函數(shù)的時候,數(shù)據(jù)類型type端該如何設(shè)置,才能使數(shù)據(jù)成功轉(zhuǎn)換類型?
這算是一個STM32的BUG嗎?
基礎(chǔ):stateflow中變量的強(qiáng)制類型轉(zhuǎn)換
清除labview的強(qiáng)制類型轉(zhuǎn)換的緩存
iOS 10-iOS 10.2.1驚現(xiàn)大BUG!按下這兩個鍵立刻死機(jī)
蘋果iOS10.2出現(xiàn)死機(jī)Bug,只需按下兩個鍵,輕松解決
強(qiáng)制類型轉(zhuǎn)換是把變量從一種類型轉(zhuǎn)換為另一種數(shù)據(jù)類型
C++之類型轉(zhuǎn)換函數(shù)詳解
STM32復(fù)位死機(jī)(無法啟動)

評論