0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

stm32一個(gè)強(qiáng)制類型轉(zhuǎn)換死機(jī)bug解讀

嵌入式情報(bào)局 ? 來(lái)源:最后一個(gè)bug ? 2023-11-30 09:31 ? 次閱讀

1情景

售后 : X工,現(xiàn)場(chǎng)出大事了,今天升級(jí)的程序跑著跑著就掛了!現(xiàn)在整個(gè)產(chǎn)線都等著這個(gè)設(shè)備恢復(fù),能安排個(gè)人過(guò)來(lái)支援下嗎?

bug菌 : my god !別慌,我問(wèn)一下負(fù)責(zé)的A工。

bug菌 : 喂,A工,昨天升級(jí)的程序有問(wèn)題,程序卡死,售后在現(xiàn)場(chǎng)你聯(lián)系一下,支援他一波,順便把程序發(fā)送給我一份,一起看看!

A工 : 啊,還有這種事,程序沒(méi)改什么呀,行,我跟售后聯(lián)系一下。

經(jīng)過(guò)一番折騰,發(fā)現(xiàn)由于程序測(cè)試不到位,導(dǎo)致了一個(gè)強(qiáng)制類型轉(zhuǎn)化引發(fā)的進(jìn)入異常,這里就分享給大家。

2bug演示

這是一個(gè)老項(xiàng)目,采用stm32F4芯片為主控,由于硬件限制而客戶又不愿意花大價(jià)錢改造,所以程序架構(gòu)等等都沒(méi)有再大動(dòng)作,由于通信上的傳輸和解析都是字節(jié)流,一些小的需求都只是在原來(lái)的通信架構(gòu)上把4個(gè)字節(jié)拆成2個(gè)字節(jié)來(lái)用,然而這一次實(shí)在沒(méi)辦法沒(méi)改接收數(shù)據(jù)類型,然后把一個(gè)double類型拆成了4個(gè)uint16來(lái)使用,沒(méi)想到出問(wèn)題了。

所以這里簡(jiǎn)單的模擬演示了一下:

wKgZomVn56OAAs5LAADmeanYIhM305.png

wKgZomVn56OADaDMAACfMRZs60g097.png

A工用一個(gè)double類型取地址,然后把地址強(qiáng)制轉(zhuǎn)為uint64_t類型,以此類型指針取內(nèi)容,當(dāng)這段代碼執(zhí)行完程序就跳到了異常中斷,導(dǎo)致死機(jī)。

其實(shí)這段代碼對(duì)于經(jīng)驗(yàn)豐富的人來(lái)說(shuō),一看就覺(jué)得很變扭,但是無(wú)論如何也不至于死機(jī)呀,畢竟強(qiáng)制類型轉(zhuǎn)化大部分人拿來(lái)都是隨便用。

3bug解讀

當(dāng)看到A工寫的這一套代碼,bug菌其實(shí)隱隱約約就感覺(jué)這塊有些問(wèn)題,但是沒(méi)敢確定,畢竟整套代碼也是前人留下的,全是邏輯沒(méi)什么精華也沒(méi)有過(guò)細(xì)研究,最后看這段代碼的匯編才知道問(wèn)題所在。

在之前bug菌也曾比較詳細(xì)的出過(guò)一篇分析此類問(wèn)題的文章,可能這一塊并沒(méi)有吸引到你,不過(guò)還是一句話:"出來(lái)混都是要還的!"。

其實(shí)問(wèn)題就出在LDRD這個(gè)ARM匯編指令上,LDRD指令表示從指定內(nèi)存地址取double word,上面圖片代碼中的LDRD R0,R1,[R2,#0x2EC],可以分解為下面兩個(gè)ldr步驟 :

wKgaomVn56OAUv0xAAApXkusAO4757.png

在ARM匯編指令集中LDRD和STRD是一對(duì)加載和提取指令,一般都需要使用__align(8)修飾來(lái)保證數(shù)據(jù)對(duì)象進(jìn)行8直接對(duì)齊,而使用#pragma pack(8)是來(lái)指定結(jié)構(gòu)體成員變量相對(duì)于第一個(gè)變量的地址的偏移量的對(duì)齊方式。

__align指示編譯器在 n 字節(jié)邊界上對(duì)齊變量,是一個(gè)存儲(chǔ)類修飾符,當(dāng)然也可以以讓2字節(jié)的對(duì)象進(jìn)行4字節(jié)對(duì)齊其與8字節(jié)對(duì)齊是等價(jià)的,一定要記得是存儲(chǔ)的起始地址為8的整數(shù)倍。

對(duì)齊可以在一定程度上提高數(shù)據(jù)提取的效率,一旦起始地址沒(méi)有對(duì)齊會(huì)導(dǎo)致對(duì)齊錯(cuò)誤,所以上面的double浮點(diǎn)類型的結(jié)構(gòu)體變量沒(méi)有8字節(jié)地址對(duì)齊,當(dāng)進(jìn)行強(qiáng)制類型轉(zhuǎn)化并使用LDRD指令就導(dǎo)致未對(duì)齊故障。

3更專業(yè)點(diǎn)

當(dāng)然對(duì)于跳轉(zhuǎn)到硬件異常的故障是非常好排查的,下面這篇文章教你如何迅速的定位故障位置和故障信息 :

對(duì)于非對(duì)齊指令的執(zhí)行會(huì)導(dǎo)致指令用法上的故障,那么Cortex芯片中相應(yīng)的故障寄存器標(biāo)志位會(huì)置位。

wKgZomVn56OAXsjIAAD6gtbDfa0001.png

wKgaomVn56OAFxOyAAEE4KKaqeA008.png

以上來(lái)自于Cortex技術(shù)文檔,文檔中也寫得非常的詳細(xì)。

當(dāng)CPU嘗試做一個(gè)未對(duì)齊的內(nèi)存訪問(wèn),然后就會(huì)發(fā)生此錯(cuò)誤。特別是對(duì)于未對(duì)齊的LDM/STM/LDRD/STRD指令,所以進(jìn)入異常中斷以后查詢芯片內(nèi)部故障寄存器也是可以找到問(wèn)題所在的,對(duì)于使用仿真器排查是再簡(jiǎn)單不過(guò)了,如果是離線排查就需要進(jìn)行上篇文章那樣打印相關(guān)日志來(lái)定位問(wèn)題。

本文來(lái)源:公眾號(hào):最后一個(gè)bug


審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2258

    文章

    10828

    瀏覽量

    352530
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4672

    瀏覽量

    67779
  • BUG
    BUG
    +關(guān)注

    關(guān)注

    0

    文章

    155

    瀏覽量

    15628

原文標(biāo)題:stm32一個(gè)強(qiáng)制類型轉(zhuǎn)換死機(jī),讓我付出了慘痛的代價(jià)~

文章出處:【微信號(hào):嵌入式情報(bào)局,微信公眾號(hào):嵌入式情報(bào)局】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)化

    可以使用強(qiáng)制類型轉(zhuǎn)換來(lái)將段內(nèi)存轉(zhuǎn)換為需要的數(shù)據(jù)類型,例如下面有
    的頭像 發(fā)表于 09-09 08:58 ?2257次閱讀
    C語(yǔ)言中<b class='flag-5'>強(qiáng)制</b><b class='flag-5'>類型</b>轉(zhuǎn)化

    TCP中強(qiáng)制類型轉(zhuǎn)換

    這是完整程序第一個(gè)和第二個(gè)強(qiáng)制類型轉(zhuǎn)換都有什么用啊我加了顯示控件,但是顯示亂碼求指點(diǎn)~~~
    發(fā)表于 04-15 19:42

    laview中強(qiáng)制類型轉(zhuǎn)換控件使用的些心得

    Labview中有個(gè)控件叫“強(qiáng)制類型轉(zhuǎn)換”,以前直沒(méi)弄明白怎么使用它,今天仔細(xì)研究了下,發(fā)現(xiàn)
    發(fā)表于 01-19 20:26

    強(qiáng)制類型轉(zhuǎn)換問(wèn)題

    本帖最后由 applevs 于 2017-5-24 23:03 編輯 char*強(qiáng)制轉(zhuǎn)換為short*后,每?jī)蓚€(gè)字節(jié)組成個(gè)新的short類型
    發(fā)表于 05-24 22:44

    個(gè)奇怪的現(xiàn)象,增加結(jié)構(gòu)節(jié)點(diǎn)后,影響強(qiáng)制類型轉(zhuǎn)換的速度

    今天做了個(gè)實(shí)驗(yàn),發(fā)現(xiàn)了很奇怪的現(xiàn)象,圖中的程序運(yùn)行非常的快,圖二中顯示了程序運(yùn)行10秒時(shí)的循環(huán)次數(shù)。然后在強(qiáng)制類型轉(zhuǎn)換外面加了
    發(fā)表于 06-08 16:07

    請(qǐng)問(wèn)使用強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換函數(shù)的時(shí)候,數(shù)據(jù)類型type端該如何設(shè)置,才能使數(shù)據(jù)成功轉(zhuǎn)換類型?

    本帖最后由 只耳朵怪 于 2018-6-26 08:51 編輯 使用強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換函數(shù)的時(shí)候,數(shù)據(jù)類型type端該如何設(shè)置,才能使
    發(fā)表于 06-25 20:33

    這算是個(gè)STM32BUG嗎?

    ,死機(jī)后串口就直發(fā)送同一個(gè)數(shù)據(jù),從仿真看是死在中斷函數(shù)里面。 猜想:STM32的其他外設(shè)也有同樣問(wèn)題。未測(cè)試。
    發(fā)表于 08-27 10:30

    基礎(chǔ):stateflow中變量的強(qiáng)制類型轉(zhuǎn)換

    使用:例:我定義了個(gè)變量speed作為輸出,某時(shí)刻指定speed=0,當(dāng)我把speed改為uint8類型,就報(bào)錯(cuò)誤,找了陣沒(méi)找到方法,就放棄了。今天在看別的帖子是發(fā)現(xiàn)了
    發(fā)表于 10-29 10:42

    C語(yǔ)言中int型強(qiáng)制類型轉(zhuǎn)換成short型的溢出問(wèn)題怎么解決?

    如何判斷STM32編碼器模式中電機(jī)的正反轉(zhuǎn)?C語(yǔ)言中int型強(qiáng)制類型轉(zhuǎn)換成short型的溢出問(wèn)題怎么解決?
    發(fā)表于 10-19 06:59

    清除labview的強(qiáng)制類型轉(zhuǎn)換的緩存

    請(qǐng)問(wèn)如何將labview的強(qiáng)制類型轉(zhuǎn)換的緩存如何清除?我在使用Picture to IMAQ image 官方vi時(shí),如果運(yùn)行時(shí)間過(guò)久,視頻流中的圖片過(guò)多,還原像素圖.vi就會(huì)造成內(nèi)存不足,
    發(fā)表于 02-15 20:36

    蘋果iOS10.2出現(xiàn)死機(jī)Bug,只需按下兩個(gè)鍵,輕松解決

    蘋果的IOS系統(tǒng),堪稱完美的用戶體驗(yàn),但是,面對(duì)目前的競(jìng)爭(zhēng),IOS的更新越來(lái)越快,頻次越來(lái)越高。所以,很多BUG的出現(xiàn),也很奇怪。最近蘋果iOS 10.2出現(xiàn)死機(jī)Bug,如何解決呢。
    發(fā)表于 02-10 00:35 ?5171次閱讀

    強(qiáng)制類型轉(zhuǎn)換是把變量從一種類型轉(zhuǎn)換為另一種數(shù)據(jù)類型

    類型轉(zhuǎn)換可以是隱式的,由編譯器自動(dòng)執(zhí)行,也可以是顯式的,通過(guò)使用強(qiáng)制類型轉(zhuǎn)換運(yùn)算符來(lái)指定。在編程時(shí),有需要
    的頭像 發(fā)表于 11-12 14:59 ?9566次閱讀

    C++之類型轉(zhuǎn)換函數(shù)詳解

    轉(zhuǎn)換構(gòu)造函數(shù)的學(xué)習(xí):1、回憶數(shù)據(jù)類型轉(zhuǎn)換:在平時(shí)寫代碼的時(shí)候,最怕的就是那種隱式數(shù)據(jù)類型轉(zhuǎn)換
    的頭像 發(fā)表于 12-24 15:31 ?754次閱讀

    STM32復(fù)位死機(jī)(無(wú)法啟動(dòng))

    STM32使用IWDG死機(jī)嗯,不知道怎么說(shuō),stm32的看門狗死機(jī)了,下面是仿真時(shí)報(bào)錯(cuò)信息:The processor has escalated a configurable-pri
    發(fā)表于 12-09 09:06 ?9次下載
    <b class='flag-5'>STM32</b>復(fù)位<b class='flag-5'>死機(jī)</b>(無(wú)法啟動(dòng))

    C語(yǔ)言如何掌握強(qiáng)制類型轉(zhuǎn)換的精髓

    強(qiáng)制類型轉(zhuǎn)換是把變量從一種類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。例如,如果您想存儲(chǔ)
    的頭像 發(fā)表于 02-26 11:00 ?386次閱讀
    C語(yǔ)言如何掌握<b class='flag-5'>強(qiáng)制</b><b class='flag-5'>類型</b><b class='flag-5'>轉(zhuǎn)換</b>的精髓