91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

數(shù)組越界的問(wèn)題解析

魚(yú)鷹談單片機(jī) ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 2023-04-17 09:15 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

數(shù)組越界問(wèn)題大家在軟件開(kāi)發(fā)過(guò)程中應(yīng)該都司空見(jiàn)慣了。如果你沒(méi)見(jiàn)過(guò),大概率是一個(gè)新手,工作經(jīng)驗(yàn)不足,倒不是說(shuō)你自己會(huì)生產(chǎn)這種 BUG,但有些同事卻可能是 BUG 搬運(yùn)工。

在魚(yú)鷹五年的工作開(kāi)發(fā)過(guò)程中,除了在北京剛畢業(yè)那會(huì)沒(méi)遇到這種隱藏問(wèn)題(碰到的都是自己生產(chǎn)的 BUG,不過(guò)自產(chǎn)自銷(xiāo),也還行),在深圳的這幾家公司都遇到了數(shù)組越界的問(wèn)題。

問(wèn)題一

第一個(gè)問(wèn)題是關(guān)于串口驅(qū)動(dòng)導(dǎo)致的越界(最終結(jié)果是 hardfault),這個(gè)魚(yú)鷹在以前的筆記中也反復(fù)強(qiáng)調(diào)了,因?yàn)檫@個(gè)問(wèn)題差點(diǎn)導(dǎo)致自己熬了一個(gè)通宵,也是醉了(老代碼的一個(gè) bug)。

當(dāng)然這個(gè)問(wèn)題的解決和當(dāng)時(shí)沒(méi)有在線調(diào)試環(huán)境(當(dāng)時(shí)的 PCB 板子通過(guò)串口燒錄代碼,沒(méi)有調(diào)試接口,大坑)有很大關(guān)系,否則解決起來(lái)會(huì)快不少。

當(dāng)然當(dāng)時(shí)魚(yú)鷹也沒(méi)掌握這個(gè)方法《BUG 終結(jié)者,現(xiàn)場(chǎng)抓獲!|顛覆認(rèn)知》,否則出現(xiàn)問(wèn)題時(shí),這種小問(wèn)題分分鐘定位它。

所以當(dāng)時(shí)解決這個(gè)問(wèn)題,全靠玄學(xué):運(yùn)氣。

否則這個(gè)問(wèn)題不知道要蹂躪魚(yú)鷹多少天。

問(wèn)題二

這個(gè)問(wèn)題在前東家遇到。當(dāng)時(shí)的環(huán)境是 boot + app 形式。boot 代碼也是跑了多年的老代碼,從來(lái)沒(méi)有出現(xiàn)過(guò)問(wèn)題。

直到有一次版本升級(jí),發(fā)現(xiàn)程序不能跳轉(zhuǎn)到 app 正常運(yùn)行(具體細(xì)節(jié)不記得了)。

當(dāng)時(shí)有同事懷疑是我當(dāng)時(shí)更新的 printf 打印函數(shù)有關(guān)系,因?yàn)楫?dāng)時(shí)的版本更新有這個(gè)改動(dòng)。但魚(yú)鷹對(duì)自己寫(xiě)的代碼還是比較有自信的,并且我的 printf 改動(dòng)和 app 跳轉(zhuǎn)能有什么關(guān)系。

但懷疑到你頭上了,同時(shí)魚(yú)鷹也經(jīng)常負(fù)責(zé)定位這類疑難雜癥,剛好空閑,那就去瞧瞧看了,證明一下這不是你的問(wèn)題。

因?yàn)閱?wèn)題 100% 復(fù)現(xiàn),又掌握了那個(gè)現(xiàn)場(chǎng)抓獲的技巧,很快就定位到是 boot 的一段代碼申請(qǐng)的棧數(shù)組空間不足,導(dǎo)致被調(diào)用的函數(shù)使用這塊空間時(shí)越界了。

類似下面這種:

func2(uint8_t*buff)
{
i=5;
buff[i]= 0;
}
fun1()
{
uint8_t buff[4];
func2(buff);
}

當(dāng)然實(shí)際代碼肯定不可能這么簡(jiǎn)單,i 的值是變化的,不可能一眼看出。

這個(gè)問(wèn)題也是導(dǎo)致 hardfault(退出 func2 時(shí),破壞了返回地址)。

看到?jīng)]有,有時(shí)候二分法(二分查找有問(wèn)題的代碼提交)查找問(wèn)題也不是那么可靠,因?yàn)閱?wèn)題可能根本不在提交的的代碼中。

而下面的問(wèn)題三也證明了這一點(diǎn)(當(dāng)然不是說(shuō)二分法沒(méi)用,只是不能全靠它作為你的結(jié)果判斷)。

問(wèn)題三

這個(gè)問(wèn)題是現(xiàn)東家遇到的問(wèn)題。

自己開(kāi)發(fā)的一個(gè)新模塊,當(dāng)合并到主分支時(shí),發(fā)現(xiàn)開(kāi)機(jī)必定 hardfault,這讓我百思不得其解。自己新加入的代碼,都沒(méi)用到數(shù)組,怎么會(huì)hardfault。

我的第一反應(yīng)就是,不是我的鍋。

但問(wèn)題出現(xiàn)在我合并的過(guò)程,也只能由我定位了。還好經(jīng)驗(yàn)豐富,一天時(shí)間+加班幾個(gè)小時(shí),總算是定位到了。

這個(gè)問(wèn)題定位有幾個(gè)難點(diǎn):

1、使用 C++

2、使用O2 優(yōu)化,而使用 O0 的方式問(wèn)題不復(fù)現(xiàn)了(最蛋疼)

3、使用了 map 庫(kù)函數(shù)

因此在復(fù)現(xiàn)率很高的情況下,還是花了這么多時(shí)間。

但好在順利解決了(這么高的復(fù)現(xiàn)率,定位root case只是時(shí)間問(wèn)題,信心也是 100%)。

簡(jiǎn)單來(lái)說(shuō),是以前的一段代碼在使用 sprintf 時(shí)(這里強(qiáng)烈建議用 snprintf),導(dǎo)致棧緩存空間越界,然后導(dǎo)致上一層函數(shù)的局部變量被篡改,而這個(gè)局部變量會(huì)導(dǎo)致 map 傳入的參數(shù)有問(wèn)題,最終導(dǎo)致了 hardfault 。

可以看到,雖然根因在一個(gè)函數(shù)中,但最終出現(xiàn)問(wèn)題卻可能在另一個(gè)函數(shù)中。

就像犯罪現(xiàn)場(chǎng),作案現(xiàn)場(chǎng)只有一個(gè)(root case),但可能案發(fā)現(xiàn)場(chǎng)并不是作案現(xiàn)場(chǎng)。

因此解決 bug 過(guò)程其實(shí)就是警察破案,通過(guò)蛛絲馬跡找到第一作案現(xiàn)場(chǎng),如此才能正確破案。

而這種代碼在工程里面有好幾處.....并且在合入我的代碼之前,運(yùn)行良好。所以,數(shù)組越界也不一定會(huì) hardfault,就看你破壞的是啥了。

為什么?

大家很奇怪,為毛數(shù)據(jù)越界大部分情況下會(huì) hardfault,有時(shí)卻不會(huì)產(chǎn)生問(wèn)題。只有思考到更深層的原因,你才能在 BUG 環(huán)繞中有所成長(zhǎng)。

這個(gè)時(shí)候,就看你的基礎(chǔ)扎實(shí)不扎實(shí)了。

這里來(lái)個(gè)簡(jiǎn)單示意函數(shù)(優(yōu)化O0)

void func2()
{
inti= 0;
intbuff[4];
 
 buff[4] = 0;
}
voidfunc1()
{
intj=0;//假設(shè)該局部變量使用r4
func2();
}

??臻g如下(因?yàn)橹挥?4 個(gè)字,編譯器可能 buff[4] 直接使用寄存器了,但為了簡(jiǎn)單說(shuō)明,這里假設(shè) buff 都使用了棧):

552128a6-dcbc-11ed-bfe3-dac502259ad0.png

從上圖我們可以知道,進(jìn)入 func2 函數(shù)時(shí),先 push,離開(kāi)時(shí) pop。

局部變量 i 使用 r4 寄存器,但是棧空間 r4 保存的是 func1 使用的j的值。

因此,當(dāng)我們數(shù)組越界時(shí)(一般越界是往高地址,因?yàn)閿?shù)組索引一般是自加),很容易破壞上一個(gè)函數(shù)的??臻g,在這里破壞的是 j 的值。如果 j 很重要,那么很可能會(huì)導(dǎo)致 hardfault 或者其它問(wèn)題(能引起 hardfault 反而是好事)。

并且這里面還有重要的返回地址 lr,如果這個(gè)值被越界破壞,那么大概率都是hardfault,因?yàn)槟闫髨D跳轉(zhuǎn)到一個(gè)不存在的地址執(zhí)行。

數(shù)組越界是一個(gè)很危險(xiǎn)的 BUG,能觀察到現(xiàn)象還好,萬(wàn)一是默默破壞而不能很快被察覺(jué),成為一個(gè)隱藏 BUG,那才是最危險(xiǎn)的。

那為啥問(wèn)題三增加別的代碼會(huì)觸發(fā)這個(gè) BUG ,修改優(yōu)化等級(jí)又會(huì)消失呢?

這和編譯器有關(guān)系,有可能你的代碼導(dǎo)致有問(wèn)題的代碼使用了不同的內(nèi)存布局,從而越界篡改的位置變成了重要的內(nèi)存,因此出現(xiàn)了現(xiàn)象,而優(yōu)化等級(jí)對(duì)棧內(nèi)存布局更是有很大影響。

另外本篇筆記介紹的局部緩存數(shù)組的越界,實(shí)際上還有全局?jǐn)?shù)組的越界,那種問(wèn)題相對(duì)簡(jiǎn)單許多,看 map 文件即可。

因此,操作數(shù)組時(shí),一定要時(shí)時(shí)刻刻檢測(cè)數(shù)組的索引的大小,以防越界。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5611

    瀏覽量

    130080
  • C++語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    147

    瀏覽量

    7699
  • 數(shù)組越界
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    5601
  • printf函數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    6294

原文標(biāo)題:數(shù)組越界是一顆隱形炸彈

文章出處:【微信號(hào):emOsprey,微信公眾號(hào):魚(yú)鷹談單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    cJSON庫(kù)是什么?

    。 2、如果是對(duì)象,那么它的一定有鍵名,先解析它的鍵名,然后解析它的值,解析值的過(guò)程與第一步一樣,遞歸解析 3、如果是數(shù)組,則逐個(gè)
    發(fā)表于 01-29 07:13

    RT-Thread Vector軟件包:嵌入式開(kāi)發(fā)的動(dòng)態(tài)數(shù)組容器 | 技術(shù)集結(jié)

    RT-Thread Vector軟件包:嵌入式開(kāi)發(fā)的動(dòng)態(tài)數(shù)組容器 | 技術(shù)集結(jié)
    的頭像 發(fā)表于 01-25 09:33 ?5448次閱讀
    RT-Thread Vector軟件包:嵌入式開(kāi)發(fā)的動(dòng)態(tài)<b class='flag-5'>數(shù)組</b>容器 | 技術(shù)集結(jié)

    容易造成單片機(jī)內(nèi)存溢出的幾個(gè)陷阱介紹

    確實(shí)會(huì)造成這個(gè)內(nèi)存訪問(wèn)錯(cuò)誤,除此之外還有一些類似的:比如像sprintf(),strcat()等函數(shù)都有可能會(huì)導(dǎo)致訪問(wèn)越界的情況發(fā)生。 還有就是數(shù)組數(shù)組也是特別容易造成訪問(wèn)越界的,有
    發(fā)表于 01-23 07:25

    Labview 解析dxf文件并顯示

    上一期開(kāi)了一個(gè)帖子講Labview導(dǎo)入dxf文件,解析和顯示dxf文件,今天繼續(xù)繼續(xù)分享常用圖元的解析與顯示方法。 LINE :用文本方式打開(kāi)dxf 文件,搜索出直線部分,并摘取,可以得到
    發(fā)表于 12-01 11:28

    數(shù)組的初體驗(yàn)

    程序中也需要容器,只不過(guò)該容器有點(diǎn)特殊,它在程序中是一塊連續(xù)的,大小固定并且里面的數(shù)據(jù)類型一致的內(nèi)存空間,它還有個(gè)好聽(tīng)的名字叫數(shù)組。可以將數(shù)組理解為大小固定,所放物品為同類的一個(gè)購(gòu)物袋,在該購(gòu) 物
    發(fā)表于 11-25 08:06

    二維數(shù)組介紹

    大家不要認(rèn)為二維數(shù)組在內(nèi)存中就是按行、列這樣二維存儲(chǔ)的,實(shí)際上,不管二維、三維數(shù)組… 都是編譯器的語(yǔ)法糖。 存儲(chǔ)上和一維數(shù)組沒(méi)有本質(zhì)區(qū)別,舉個(gè)例子: int array[3][3
    發(fā)表于 11-25 07:42

    上位機(jī)報(bào)錯(cuò)2033問(wèn)題處理方案

    、解決方案三個(gè)維度,系統(tǒng)性地分析該問(wèn)題的處理流程。 一、錯(cuò)誤機(jī)理深度解析 報(bào)錯(cuò)2033的本質(zhì)是內(nèi)存地址訪問(wèn)沖突,通常發(fā)生在以下場(chǎng)景: 1. 指針越界操作:當(dāng)程序試圖通過(guò)指針訪問(wèn)未被分配的內(nèi)存區(qū)域時(shí)(如數(shù)組
    的頭像 發(fā)表于 11-13 17:40 ?887次閱讀

    精彩回顧 | 《器件選型EMC問(wèn)題解析與交流》直播圓滿結(jié)束!

    賽盛技術(shù)于11月12日18:30舉辦了《器件選型EMC問(wèn)題解析與交流》專題直播。感謝每一位觀眾的熱情參與與支持,讓我們的直播活動(dòng)得以圓滿落幕。在此,小編將帶大家一起回顧本次直播中的精彩亮點(diǎn)。讓我們
    的頭像 發(fā)表于 11-13 15:13 ?557次閱讀
    精彩回顧 | 《器件選型EMC問(wèn)<b class='flag-5'>題解析</b>與交流》直播圓滿結(jié)束!

    精彩回顧 | 《電源EMC問(wèn)題解析與交流》直播圓滿結(jié)束!

    賽盛技術(shù)于10月29日18:30舉辦了《電源EMC問(wèn)題解析與交流》專題直播。感謝每一位觀眾的熱情參與與支持,讓我們的直播活動(dòng)得以圓滿落幕。在此,小編將帶大家一起回顧本次直播中的精彩亮點(diǎn)。讓我們一同
    的頭像 發(fā)表于 10-30 17:24 ?1139次閱讀
    精彩回顧 | 《電源EMC問(wèn)<b class='flag-5'>題解析</b>與交流》直播圓滿結(jié)束!

    野外地物光譜儀的常見(jiàn)問(wèn)題解析

    光譜儀的使用和功能提出了很多疑問(wèn)。本文將深入解析用戶在使用野外地物光譜儀時(shí)常見(jiàn)的5大問(wèn)題,幫助用戶更好地理解該技術(shù),增強(qiáng)品牌信任度。 1. 什么是野外地物光譜儀? 野外地物光譜儀是一種用于收集地面物體反射光譜數(shù)據(jù)的設(shè)備,這些
    的頭像 發(fā)表于 10-30 10:42 ?292次閱讀

    rt_malloc_align函數(shù)內(nèi)存越界問(wèn)題怎么解決?

    字節(jié)用來(lái)保存真實(shí)申請(qǐng)的內(nèi)存地址(0x2000001),而0x2000000并不是申請(qǐng)到的內(nèi)存,會(huì)造成內(nèi)存越界操作。
    發(fā)表于 09-22 08:30

    mqtt dns解析失敗是為什么?

    解析域名的ip地址就能正常連上,而直接解析域名就不行,為什么呢
    發(fā)表于 09-16 06:38

    變頻器與傳動(dòng)使用的常見(jiàn)問(wèn)題解

    變頻器與傳動(dòng)系統(tǒng)作為工業(yè)自動(dòng)化領(lǐng)域的核心設(shè)備,其穩(wěn)定運(yùn)行直接影響生產(chǎn)效率和設(shè)備壽命。以下是針對(duì)實(shí)際應(yīng)用中高頻問(wèn)題的系統(tǒng)性解答,結(jié)合技術(shù)原理與現(xiàn)場(chǎng)經(jīng)驗(yàn),為從業(yè)者提供實(shí)用參考。 一、電機(jī)過(guò)熱問(wèn)題解析
    的頭像 發(fā)表于 06-10 07:35 ?728次閱讀
    變頻器與傳動(dòng)使用的常見(jiàn)問(wèn)<b class='flag-5'>題解</b>答

    精彩回顧 | 《電磁兼容仿真技術(shù)與電源EMC問(wèn)題解析》直播圓滿結(jié)束!

    賽盛技術(shù)于4月22日19:00舉辦了《電磁兼容仿真技術(shù)與電源EMC問(wèn)題解析》專題直播。感謝每一位觀眾的熱情參與與支持,讓我們的直播活動(dòng)得以圓滿落幕。在此,小編將帶大家一起回顧本次直播中的精彩亮點(diǎn)
    的頭像 發(fā)表于 04-23 11:24 ?893次閱讀
    精彩回顧 | 《電磁兼容仿真技術(shù)與電源EMC問(wèn)<b class='flag-5'>題解析</b>》直播圓滿結(jié)束!

    part 3 模擬電子技術(shù)基礎(chǔ)(第四版)習(xí)題解答-童詩(shī)白

    模擬電子技術(shù)基礎(chǔ)(第四版)習(xí)題解答-童詩(shī)白
    發(fā)表于 03-27 10:44