<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

程序中增加一個變量導致異常的分析

typedef ? 來源:typedef ? 2024-01-22 09:56 ? 次閱讀

前述

大家在平常的編程過程應該會碰到各種奇葩的問題吧,反正我最近是碰到了一次,再此跟大家分享一下。事情的原因是我在程序中增加了一個變量,然后就會導致程序每次都會進入異常。

示例代碼

我將代碼簡化了,使用兩個模塊來演示這個問題。第一個模塊是Dev模塊。

下面是Dev模塊的頭文件,Dev結構體中有一個數組。

#include
#include

typedefstruct{
inta_[100];
charb_;
}Dev;

voidDevInit(Dev*c_this);

下面是Dev模塊的源文件代碼,里面只有一個memset。

#include"Dev.h"

voidDevInit(Dev*c_this){
memset(c_this,0,sizeof(Dev));
}

第二個模塊是DevManager,相關數據結構如下:

#include"Dev.h"

#pragmapack(1)

typedefstruct{
Devuart_;
charnum_;//Addingthisvariablecausesacrash
Deviic_;
}DevManage;

#pragmapack()

DevManagedev_manage;

voidDevManagerInit(void){
DevManage*c_this=&dev_manage;

memset(c_this,0,sizeof(DevManage));

DevInit(&c_this->uart_);
DevInit(&c_this->iic_);
}

DevManage結構體包含uart以及iic設備,以及我新加入的一個num_變量,由于新增了num_變量以及與之相關的業務會導致每次調試目標板都會進入異常。

嘗試解決異常問題

根據調試情況看,每次都會出現異常,說明是個小問題。就怕偶爾出現異常,不容易復現。

思路應該非常清晰,出現異常時候查看LR寄存器的值,LR寄存器主要有兩個功能。

保存子程序返回地址。使用BL或BLX時,跳轉指令自動把返回地址放入r14中

當異常發生時,異常模式的R14用來保存異常返回地址

根據LR寄存器的值,從而定位到是執行DevInit(&c_this->iic_)函數中的memset導致的。

第一反應是DevInit中傳入的對象可能為空,操作了非法內存才導致的錯誤。于是又重新調試了一遍,發現DevInit中對象的地址并不為空,而且就是等于實體對象中設備的地址。

這一刻我陷入了深深的自我懷疑,memset難道不是這樣用的?難道不是傳入一個地址,清0,然后sizeof(DevManage)就完事了?

我這代碼怎么會出錯,memset就是這樣用的,天王老子來我也是對的,這樣的心理是不是也深度還原了碰到問題時的你們。

如果是你,該如何繼續...

救命稻草

有人說,匯編是最后的救命稻草。那我也嘗試抓住這根稻草,出現問題時如下圖:

1b2d08ce-b8c4-11ee-8b88-92fbcf53809c.png

問題主要出現紅色箭頭指向的這一行,經過查詢資料得知_aeabi_memclr4是一個用于ARM嵌入式系統的函數,用于將內存區域清零。函數名中的"_a"表示該函數符合ARM嵌入式應用二進制接口(Embedded Application Binary Interface,EABI)規范。在調用_aeabi_memclr4時,需要確保傳入的內存地址是四字節對齊的。再看圖片中的對象地址為0x200001BD,剛好比四字節對齊地址0x200001BC多了一個字節。

再回頭看DevManage對象,這里使用了偽指令#pragma pack(1)讓內存分配進行單字節對齊。因為Dev對象是按照四字節對齊的,緊接著引入了新的成員num_占用一個字節。所以導致iic_對象的地址相對于未增加變量之前的地址偏移了一個字節,導致不是四字節對齊的了,從而引發了錯誤。

就示例中的代碼而言,只需要把強制DevManage對象單字節對齊的功能刪除即可解決問題,因為默認情況下是四字節對齊的。

成員分配

由于#pragma pack(1)具有作用域限制,這里其實只是對num_變量做了單字節對齊的限制,而并沒有對Dev對象的內存分配起到限制作用,Dev對象仍然是按照4字節對齊的(默認值),所以Dev對象的所占用的長度一定是101*4=404字節。而整個DevManager對象的大小就101 * 4 + 1 + 101 * 4 = 809字節,成員分配如下圖所示。

1b37ac7a-b8c4-11ee-8b88-92fbcf53809c.png

最后

到最后在拋出一個問題,對于上述的代碼在vscode中使用gcc編譯執行為何沒有問題?

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2513

    瀏覽量

    46681
  • 編程
    +關注

    關注

    88

    文章

    3445

    瀏覽量

    92652
  • 程序
    +關注

    關注

    114

    文章

    3633

    瀏覽量

    79695
  • 變量
    +關注

    關注

    0

    文章

    598

    瀏覽量

    28139

原文標題:加個變量,程序崩了

文章出處:【微信號:typedef,微信公眾號:typedef】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    數據波形數據異常分析

    ,試驗過程,V1-的電壓出現了異常點3.95V(試驗進行了7、8小時后),如下圖所示,左側圖為持續監控圖,右側圖為正常傳感器的監控圖
    發表于 11-21 11:55

    系統變更(增加新的狀態遷移條件),導致在某些狀態時技術器出現異常,求可能的原因?

    系統變更(增加新的狀態遷移條件),導致在某些狀態時技術器出現異常,求可能的原因?
    發表于 08-23 21:31

    Java的常用異常處理方法 java推薦

    放在異常可能發生的地方,具體用法如下:try{// 程序代碼}catch(ExceptionName e1){//Catch 塊}catch 語句包含要捕獲異常類型的聲明。當保護代碼塊中發生
    發表于 01-19 17:26

    分析關于STM32 芯片異常復位的經典案例!

    應用軟件產生異常的地方!問題描述某STM32用戶反饋,當使用STM32L4芯片的時候,程序運行段時間后,會忽然復位。復位后程序繼續運行,但是還會繼續復位,原因不詳!問題
    發表于 04-07 08:00

    DSP中斷處理程序導致異常

    下午好。我的處境很簡單(或者應該是這樣)。我有DMA從ADC消耗并行數據。當塊完成時,DMA中斷使用FFT庫函數來計算頻譜內容。這個例程本身可以正常工作。但是,當我將
    發表于 03-20 08:48

    導致STM32進入HardFault異常的原因

    1、導致異常的原因有很多,例如:直接使用未分配空間的指針、棧溢出等異常非法操作便會使程序進入“HardFault”異常狀態。接下來在MDK工
    發表于 01-07 06:52

    STM32局部變量過大導致棧溢出怎么去解決呢

    最近項目調試中發現只要使用memset函數對局部數組賦值時,就會導致其他全局變量值被更改,接著就進入HardFault錯誤。后來發現局部變量
    發表于 01-20 06:07

    Labview的異常崩潰

    起因:昨天升級程序后產線突然反饋程序異常崩潰,排查到了神奇的BUG。Labview異常崩潰報
    發表于 03-17 18:05

    請問main函數內定義的變量是在棧上嗎?

    程序調試很久直數據異常,后來無意發現main函數內定義的變量定義在main以外后程序功能正
    發表于 04-01 10:12

    如何在兩程序交換變量值?

    的扇區 0 上運行。)作為參考,我使用 STM32CubeIDE 1.3.0 作為編譯工具。以前用IAR的時候,程序的兩變量放在noinit區的同
    發表于 02-08 08:38

    XDATA定義變量程序異常的原因?怎么解決?

    本人第次使用新塘N76E003單片機開發,在定義變量時DATA用完了以后,使用XDATA定義變量,發現用XDATA定義的變量程序運行時
    發表于 06-25 06:05

    變量水質參數時間異常事件檢測算法

    在供水管網中部署傳感器網絡實時獲取多個水質參數時間序列數據,當供水管網發生污染時,高效準確地檢測水質異常是一個重要問題。提出多變量水質參數時間異常事件檢測算法( M-TAEDA),利用BP模型
    發表于 12-07 16:17 ?0次下載
    多<b class='flag-5'>變量</b>水質參數時間<b class='flag-5'>異常</b>事件檢測算法

    C程序流程設計之變量

    變量是對程序中數據的存儲空間的抽象,變量的屬性,數據類型:變量所持有的數據的性質(操作屬性)
    的頭像 發表于 02-17 14:08 ?500次閱讀
    C<b class='flag-5'>程序</b>流程設計之<b class='flag-5'>變量</b>

    Java oom異常的原因分析

    據,而棧內存用于存儲方法調用和局部變量。 當程序需要使用更多內存時,會向操作系統請求更多的內存空間。如果操作系統無法分配足夠的內存空間,就會導致OOM異常的發生。
    的頭像 發表于 12-05 13:43 ?357次閱讀

    變量位置不同會死機?郭天祥老師視頻的遺留問題分析答案

    在郭天祥老師視頻里有一個問題分享,是EXMC初始化里的一個變量定義和初始化位置不同會導致程序死機,最終定位到程序是進入hardfault死機,但暫時沒有后續
    的頭像 發表于 02-26 09:12 ?150次閱讀
    <b class='flag-5'>變量</b>位置不同會死機?郭天祥老師視頻的遺留問題<b class='flag-5'>分析</b>答案
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>