0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MSP430数组填充越界引起的栈溢出导致程序跑飞如何解决

2oON_changxuemc 来源:未知 2019-05-26 12:01 次阅读

一、预备知识

1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

(这是一个前辈写的,非常详细)

//main.cpp

inta=0;全局初始化区

char*p1;全局未初始化区

main()

{

intb;栈

chars[]="abc";栈

char*p2;栈

char*p3="123456";123456在常量区,p3在栈上。

staticintc=0;全局(静态)初始化区

p1=(char*)malloc(10);

p2=(char*)malloc(20);

分配得来得10和20字节的区域就在堆区。

strcpy(p1,"123456");123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}

二、堆和栈的理论知识

2.1申请方式

stack:

由系统自动分配。例如,声明在函数中一个局部变量intb;系统自动在栈中为b开辟空间

heap:

需要程序员自己申请,并指明大小,在c中malloc函数

如p1=(char*)malloc(10);

C++中用new运算符

如p2=(char*)malloc(10);

但是注意p1、p2本身是在栈中的。

MSP430 堆栈溢出 解决

MSP430程序在运行的过程中,出现死机的现象,通过IAR编译器观察,死机的原因是栈溢出。

因为定义的局部变量是在栈内的,所以分析可能是局部变量导致栈溢出,最有可能导致编译器不能事先判断

使用了多少栈的(超出设定值会报警),就是程序中产生新的占用栈的变量,由之前的经验推测是数组越界,因为如果程序不顾数组的边界,越界不断的往里填东西,越界的部分就会被当成局部变量,占用栈的内存。

因为栈是从RAM的底部网上长(存数据)的,而其他程序运行的数据是从顶部往下的,所以当栈越存越多,越积越高的时候,栈就会和程序运行时的数据碰头,二者占满整个RAM内存,此时栈再继续消耗,栈再向上长,直接覆盖掉程序运行时所需的变量,程序就要跑飞了。

(iar430中定义的变量是从ram的起始地址向上(由小到大),而堆栈是从ram的终止地址向下(由大到小)。

以msp430F5438为例,它是16KB的ram,起始地址为0x1C00h,终止地址为005BFFh(data sheet 15页),所以它的变量是从0x1C00h开始,向0x005BFFh方向存放,而堆栈是从0x005BFFh开始,向0x1C00h方向压栈。当变量存储空间和堆栈最大占用空间在中间相遇时,就发生了堆栈溢出。)

下面就详细介绍如何查看ram使用情况:

1当然是烧程序到目标板里呀

2选择view/memory,打开memory窗口

3从ram的起始地址0x1C00h开始,输入0x3fff(16KB),再回车

4选中0x1C00h~0x005BFFh区域,右键选择memory fill……

5在memory fill中的start写入:0x1C00h,length写:0x3fff,value填入FF(也可填入其他值),被选中的区域全填充FF

6运行程序,跑一遍设计的所有功能,再停止cspy,看看memory窗口

7如果再填充的区域内已经没有FF存在,就说明已经发生堆栈溢出或是会有溢出的危险(ram刚好够用)。最好保留一定余量的ram不被改变,以防发生溢出

验证:定义一个UART0_RX_HEX_BUF[400];

在程序中加入这个代码。

unsigned int i;

for(i=0;i<17000;i++)

UART0_RX_HEX_BUF[i]=0xFA;

因为MSP430的RAM只有16KB,所以填17000次(char)足以保证栈全部占满RAM,覆盖掉所以运行程序的变量,导致跑飞。

程序运行结果是,程序跑飞。产看栈STACK,栈溢出。假设应该是正确的。

因而分析导致栈溢出的程序段应该是这里:

红色部分当时是为了避免中断程序过长跟不上中断,使得数据收不全而去掉的,现在分析if(UART0_RX_HEX_Len >= UART0_RX_HEX_MAXLen)

UART0_RX_HEX_Len = 0;

这两句子不能去掉,因为,在没有接收到协议数据(配置数据,FE……FA)之前,UART0_RX_HEX_BUF和UART0_RX_BUF一样在接收返回的AT指令返回,数组在不断的填装,UART0_RX_BUF每隔一段时间就会被读取一次,并清空,因而不会出现溢出。但是在没有收到配置数据之前,UART0_RX_HEX_BUF不会清空,且在配置完之后,只要服务站不发协议数据,也不会清空,因而UART0_RX_HEX_BUF基本处于只填装不清空的状态,最后远远越界,最终导致开头分析的结果。

加了清零语句:

if(UART0_RX_HEX_Len >= UART0_RX_HEX_MAXLen)

UART0_RX_HEX_Len = 0;

后,死机在12小时内在没有出现,其他比对机器全部死机,初步证明分析应该是正确的。

#pragma vector=USCI_A0_VECTOR

__interrupt void USCI_A0_ISR()

{

UCA3TXBUF=UCA0RXBUF;//把接收的数据发到U3便于观察(LCX注)

//接收字符数据时

UART0_RX_BUF[UART0_RX_Len] = UCA0RXBUF;

UART0_RX_Len++;

ReadUART0_new=Read_Cycle;

//接收协议数据时(16进制)

UART0_RX_HEX_BUF[UART0_RX_HEX_Len] = UCA0RXBUF;

if((UART0_RX_HEX_BUF[UART0_RX_HEX_Len]==0xFF)&&(UART0_RX_HEX_BUF[UART0_RX_HEX_Len-1]==0xFE))

{

UART0_RX_HEX_BUF[0]=UART0_RX_HEX_BUF[UART0_RX_HEX_Len-1];

UART0_RX_HEX_BUF[1]=UART0_RX_HEX_BUF[UART0_RX_HEX_Len];

UART0_RX_HEX_Len=1;

}

else if((UART0_RX_HEX_BUF[UART0_RX_HEX_Len]==0xFA)&&(UART0_RX_HEX_BUF[UART0_RX_HEX_Len-1]==0xFF))

{

ReadUART0_Permit=1;

UCA0IE &= ~ UCRXIE;

}

UART0_RX_HEX_Len++;

if(UART0_RX_HEX_Len >= UART0_RX_HEX_MAXLen)

UART0_RX_HEX_Len = 0;

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • msp430
    +关注

    关注

    180

    文章

    2403

    浏览量

    229302
  • 程序
    +关注

    关注

    117

    文章

    3785

    浏览量

    81006
  • 编译器
    +关注

    关注

    1

    文章

    1624

    浏览量

    49108
  • 数组
    +关注

    关注

    1

    文章

    417

    浏览量

    25939

原文标题:MSP430 数组填充越界引起的栈溢出 导致程序跑飞

文章出处:【微信号:changxuemcu,微信公众号:畅学单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MSP430问题求确认

    ,可能在申请大局部变量的时候堆栈溢出。求证,请问我这个判断成立吗?还有别的可能吗?还有就是堆栈溢出死机但是看门狗没有复位,是因为程序大量地方清狗,导致
    发表于 03-05 15:35

    MSP430程序之解决方法

    msp430程序之解决方法1.中断或主函数中有死循环,现象是程序停在某处。2.堆栈溢出。现象
    发表于 08-05 11:53

    MSP430FE427 MSP430F149 IAR

    不知道是仿真器问题还是程序问题(程序公司出货几百万台产品的正式代码,不可能出问题)。一个单步调试居然跑了几分钟都过不去,还好偶尔出现溢出
    发表于 11-18 00:21

    如何对MSP430进行开发并调试呢

    转载及积累:1、分配数组的时候,一定要够长,否则填入是数组越界的时候,造成很多的问题(包括潜在的问题)。a:全局变量改变:越界数据将全局变量覆盖b:
    发表于 11-29 06:01

    单片机程序原因是什么

    参考:单片机程序?作者:嵌入式ARM网址:https://mp.weixin.qq.com/s/a22zVdSfCqWjSmlBxK2R1Q目录数组
    发表于 12-13 07:17

    单片机程序的几种原因

    溢出)的错误,仔细检查函数中调用的数组是否存在越界溢出)的情况。2 、中断服务程序缺失现象:程序
    发表于 11-30 12:57

    对于一个数组为什么越界使用会导致MCU的程序呢?

    对于一个数组为什么越界使用会导致MCU的程序
    发表于 10-13 06:01

    nrf2401的msp430程序

    nrf2401的msp430程序
    发表于 04-11 09:59 172次下载
    nrf2401的<b class='flag-5'>msp430</b><b class='flag-5'>程序</b>

    MSP430 C语言编程的程序堆栈溢出分析

    MSP430 C语言编程的程序堆栈溢出分析
    发表于 05-16 15:04 40次下载

    sed1335的msp430程序

    sed1335的msp430程序 MSP430子程
    发表于 04-11 09:53 1159次阅读

    msp430的实验程序

    msp430的实验程序代码,共七个基础性的简单实验。
    发表于 04-28 15:35 6次下载

    msp430延时程序设计

    msp430延时程序设计msp430延时程序设计msp430延时程序设计
    发表于 04-29 14:40 0次下载

    MSP430单片机教程之MSP430的详细程序示例合集免费下载

    本文档的主要内容详细介绍的是MSP430单片机教程之MSP430的详细程序示例合集免费下载。
    发表于 09-13 08:00 197次下载

    、死机】单片机 msp430程序原因和解决方式积累

    1.中断或主函数中有死循环,现象是程序停在某处。 2.堆栈溢出。现象是程序。 *****************************
    发表于 11-19 17:51 22次下载
    【<b class='flag-5'>跑</b><b class='flag-5'>飞</b>、死机】单片机 <b class='flag-5'>msp430</b><b class='flag-5'>程序</b><b class='flag-5'>跑</b><b class='flag-5'>飞</b>原因和解决方式积累

    【单机片调试】开发调试MSP430 遇到的问题总结

    程序。 2、定义一个全局变量(数组),当变量(数组)很长的时候出现,能下载到单片机,但不能运行的情况。例: char UART0
    发表于 11-19 18:36 14次下载
    【单机片调试】开发调试<b class='flag-5'>MSP430</b> 遇到的问题总结