18video性欧美19sex,欧美高清videosddfsexhd,性少妇videosexfreexxx片中国,激情五月激情综合五月看花,亚洲人成网77777色在线播放

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

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

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

問題一

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

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

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

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

否則這個問題不知道要蹂躪魚鷹多少天。

問題二

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

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

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

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

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

類似下面這種:

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

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

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

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

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

問題三

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

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

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

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

這個問題定位有幾個難點:

1、使用 C++

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

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

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

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

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

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

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

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

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

為什么?

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

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

這里來個簡單示意函數(shù)(優(yōu)化O0)

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

棧空間如下(因為只有 4 個字,編譯器可能 buff[4] 直接使用寄存器了,但為了簡單說明,這里假設(shè) buff 都使用了棧):

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

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

局部變量 i 使用 r4 寄存器,但是??臻g r4 保存的是 func1 使用的j的值。

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

并且這里面還有重要的返回地址 lr,如果這個值被越界破壞,那么大概率都是hardfault,因為你企圖跳轉(zhuǎn)到一個不存在的地址執(zhí)行。

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

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

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

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

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





審核編輯:劉清

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

    關(guān)注

    31

    文章

    5503

    瀏覽量

    128263
  • C++語言
    +關(guān)注

    關(guān)注

    0

    文章

    147

    瀏覽量

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

    關(guān)注

    0

    文章

    2

    瀏覽量

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

    關(guān)注

    0

    文章

    31

    瀏覽量

    6199

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

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

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

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

    mqtt dns解析失敗是為什么?

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

    變頻器與傳動使用的常見問題解

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

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

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

    stm32 DMA串口接收到數(shù)組數(shù)組元素順序錯亂怎么解決?

    配置DMA循環(huán)模式,使用HAL_UART_Receive_DMA(&huart1,buffer,4)函數(shù)將串口數(shù)據(jù)循環(huán)發(fā)送到4個元素的buffer數(shù)組內(nèi),上位機(jī)20ms發(fā)送一次
    發(fā)表于 03-12 08:02

    【電磁兼容技術(shù)案例分享】USB屏蔽電纜接頭搭接導(dǎo)致的BCI問題解決案例

    【電磁兼容技術(shù)案例分享】USB屏蔽電纜接頭搭接導(dǎo)致的BCI問題解決案例
    的頭像 發(fā)表于 02-11 09:41 ?798次閱讀
    【電磁兼容技術(shù)案例分享】USB屏蔽電纜接頭搭接導(dǎo)致的BCI問<b class='flag-5'>題解</b>決案例

    EE-175: 仿真器與EZ-KIT Lite評估系統(tǒng)問題解決指南

    電子發(fā)燒友網(wǎng)站提供《EE-175: 仿真器與EZ-KIT Lite評估系統(tǒng)問題解決指南.pdf》資料免費(fèi)下載
    發(fā)表于 01-08 14:41 ?0次下載
    EE-175: 仿真器與EZ-KIT Lite評估系統(tǒng)問<b class='flag-5'>題解</b>決指南

    數(shù)組的下標(biāo)為什么可以是負(fù)數(shù)

    最近有同學(xué)發(fā)來這樣一段代碼,并提出一個問題,數(shù)組的下標(biāo)為什么可以是負(fù)數(shù)? ? ? #include int main(){ const char *s = "helloworld"; const
    的頭像 發(fā)表于 12-20 11:18 ?735次閱讀

    C2000常見問題解

    電子發(fā)燒友網(wǎng)站提供《C2000常見問題解答.pdf》資料免費(fèi)下載
    發(fā)表于 12-06 16:04 ?0次下載
    C2000常見問<b class='flag-5'>題解</b>答

    數(shù)組名之間可以直接賦值嗎

    數(shù)組之間的賦值能不能直接使用等于號?比如這樣的代碼。 int main(){ int a[5] = {1, 2, 3, 4, 5}; int b[5] = {0}; b = a
    的頭像 發(fā)表于 11-26 11:23 ?836次閱讀

    指針數(shù)組和二維數(shù)組有沒有區(qū)別

    指針數(shù)組和二維數(shù)組有沒有區(qū)別?比如這樣的兩個代碼。 int main(){ char *s1[] = { "hello", "world", "total" }; char s2[][6
    的頭像 發(fā)表于 11-24 11:12 ?691次閱讀

    C語言數(shù)組應(yīng)用計算機(jī)導(dǎo)論A第6講:數(shù)組

    C語言數(shù)組應(yīng)用計算機(jī)導(dǎo)論A第6講:數(shù)組
    發(fā)表于 11-20 15:33 ?1次下載

    解讀版|Air780E軟件中C語言內(nèi)存數(shù)組的神秘面紗!

    今天我們來揭開Air780E 軟件中 C 語言內(nèi)存數(shù)組的神秘面紗,希望有所收獲。
    的頭像 發(fā)表于 11-17 10:00 ?837次閱讀
    解讀版|Air780E軟件中C語言內(nèi)存<b class='flag-5'>數(shù)組</b>的神秘面紗!

    【電磁兼容技術(shù)案例分享】屏蔽罩結(jié)構(gòu)縫隙導(dǎo)致輻射發(fā)射問題解決案例

    【電磁兼容技術(shù)案例分享】屏蔽罩結(jié)構(gòu)縫隙導(dǎo)致輻射發(fā)射問題解決案例
    的頭像 發(fā)表于 11-07 08:03 ?858次閱讀
    【電磁兼容技術(shù)案例分享】屏蔽罩結(jié)構(gòu)縫隙導(dǎo)致輻射發(fā)射問<b class='flag-5'>題解</b>決案例

    電路設(shè)計常見問題解

    電路設(shè)計充滿挑戰(zhàn),即便是最富經(jīng)驗的工程師也難免遭遇困惑與阻礙?!峨娐吩O(shè)計常見問題解答》是ADI精心籌備的一份實用指南,力求為您鋪設(shè)一條清晰的學(xué)習(xí)與實踐之路。
    的頭像 發(fā)表于 11-05 17:02 ?1385次閱讀
    電路設(shè)計常見問<b class='flag-5'>題解</b>答