OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14938|回复: 19

STM32如何解决堆栈溢出问题及详细分析溢出原因

[复制链接]

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
发表于 2016-12-9 09:51:31 | 显示全部楼层 |阅读模式
在开发过程中,我们有时候可能会遇到数据错误的情况,而这个情况发生多数是由于堆栈溢出导致,这里我们将详细讲解复现堆栈溢出会导致的问题及提供相应的解决方法。
1 .建立一个测试工程
1-函数定义.png
定义主函数
2-堆栈空间大小定义.png
定义堆栈地址大小,分别都定义为0x00000200
5-栈地址.png
编译后查看生成的.map文件,可以看到栈起始地址为0x20000d50,大小为512byte
2. 理论计算分析
程序定义了全局变量大小为32位(对应4字节)的700个数据,所以全局变量占用RAM空间计算:
G=0x20000000 + 4*700 = 0x20000AF0
由于栈地址是向下生长方式,我们定义了局部变量数据大小为50032位的数,所以实际运行时局部变量占用RAM的起始地址为:
L=0x20000D50 + 512 – 4*500 = 0x20000780
所以局部变量占用RAM的地址范围为:0x20000780 --- 0x20000F50
由上计算可知,局部变量部分地址空间与全局变量使用的地址空间有冲突,这将导致程序运行过程全局变量数值被局部变量替换掉。
3. 测试论证
程序运行测试如下图所示:
3-1全局变量初始化.png
3-2全局变量初始化.png
全局变量初始化完成
4-1局部变量存储起始地址.png
初始化局部变量,由上图可看出原来全局变量的数值已被局部变量替换
4. 解决方法
4.1 理论计算
由之前可以算出局部变量使用了2000byte的RAM地址空间,由于堆栈地址设置要求是0x0100的整数倍,所以这里可以将大小设置为0x0800,即2048个字节数据。
4.2 设置栈空间大小
改大栈空间大小,如下图所示:
7-改大栈空间大小.png
修改栈空间大小后查看生成的.map文件,如下图所示:
8-变大后的map图.png
4.3 修改后测试验证
6-栈修改后起始地址.png
由上图测试可以知道,局部变量存储地址已经从0x20000D80开始,与全局变量存储地址不冲突,至此可以解决遇到的堆栈溢出问题。
         上述方法已解决了我们遇到的堆栈溢出问题,但实际编程时,我们不建议在子函数中使用大数组,需要源代码的朋友请添加QQ707372788索取。
    关注微信公众号:嵌入式STM32软硬件开发,让自己每周都学多一点嵌入式开发吧


嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-12-9 09:53:21 | 显示全部楼层
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-9 09:55:11 | 显示全部楼层

谢谢,关注微信公众号,每周都有精神内容分享噢
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3708
金钱
3708
注册时间
2011-5-23
在线时间
2010 小时
发表于 2016-12-9 10:09:14 | 显示全部楼层
有MPU的平台,使用MPU的两个region来分别做中断栈和线程线的保护,这样当栈触碰到底时,会给出指示。

当然,为了省空间,一般保护块只设最小的32字节。
如果是栈上直接开大数据或结构体,可能会直接跳过保护区。
还是芯片自带栈保护功能比较保险
RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2770
金钱
2770
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-12-9 10:30:17 | 显示全部楼层
谢谢楼主,最近刚好遇到相关问题,学习一下。
自在随心
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-9 11:26:51 | 显示全部楼层
yuzeyuan1 发表于 2016-12-9 10:30
谢谢楼主,最近刚好遇到相关问题,学习一下。

嗯嗯   关注我的微信公众号:嵌入式STM32软硬件开发      每周至少一篇超有价值的开发文章分享      
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3765
金钱
3765
注册时间
2015-4-26
在线时间
762 小时
发表于 2016-12-9 16:16:50 | 显示全部楼层
0x20000D50是起始地址,那下面这个式子 +512 是什么意思?
L=0x20000D50 + 512 – 4*500 = 0x20000780
堆栈向下增长的话,就不需要 +512了吧。
我有故事,你有酒吗
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
发表于 2016-12-10 13:03:38 | 显示全部楼层
来俩不甜的 发表于 2016-12-9 16:16
0x20000D50是起始地址,那下面这个式子 +512 是什么意思?
L=0x20000D50 + 512 – 4*500 = 0x20000780
堆 ...

栈的范围就是0x20000D50 ->0x20000D50 + 512
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-10 16:05:10 来自手机 | 显示全部楼层
8楼正解
回复 支持 反对

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3765
金钱
3765
注册时间
2015-4-26
在线时间
762 小时
发表于 2016-12-10 19:57:14 | 显示全部楼层
战舰水手 发表于 2016-12-10 13:03
栈的范围就是0x20000D50 ->0x20000D50 + 512

向下增长什么意思,我感觉是 20000d50 ~ 20000d50-512
我有故事,你有酒吗
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-11 14:44:55 | 显示全部楼层
来俩不甜的 发表于 2016-12-10 19:57
向下增长什么意思,我感觉是 20000d50 ~ 20000d50-512

向下增长是指数据存储的方式,栈范围是你定义的栈空间,这是两回事,不知道你懂了没有呢
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3765
金钱
3765
注册时间
2015-4-26
在线时间
762 小时
发表于 2016-12-11 19:23:49 | 显示全部楼层
stm32你是我的菜噢 发表于 2016-12-11 14:44
向下增长是指数据存储的方式,栈范围是你定义的栈空间,这是两回事,不知道你懂了没有呢

能看得出来是这个意思,还想知道这种东西哪有讲解的?
我有故事,你有酒吗
回复 支持 反对

使用道具 举报

8

主题

97

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
17561
金钱
17561
注册时间
2016-1-20
在线时间
63 小时
发表于 2016-12-12 09:28:56 | 显示全部楼层
确实是好贴 ,这种方法很靠谱,一直寻找可以用软件查找这些问题,却找不到
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-13 09:22:22 | 显示全部楼层
YMC 发表于 2016-12-12 09:28
确实是好贴 ,这种方法很靠谱,一直寻找可以用软件查找这些问题,却找不到

谢谢,
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-13 09:23:19 | 显示全部楼层
来俩不甜的 发表于 2016-12-11 19:23
能看得出来是这个意思,还想知道这种东西哪有讲解的?

几乎没有,我是没找到,所以我要做这个公众号,麻烦关注下哦,谢谢
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-15 11:10:02 | 显示全部楼层
自己顶一次,哈哈
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

1

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
318
金钱
318
注册时间
2016-10-17
在线时间
98 小时
发表于 2016-12-19 14:24:34 | 显示全部楼层
已关注,讲得很好,学习了
回复 支持 反对

使用道具 举报

39

主题

212

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-4-21
在线时间
129 小时
发表于 2016-12-19 14:34:45 | 显示全部楼层
nice!!!
回复 支持 反对

使用道具 举报

6

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2015-9-22
在线时间
32 小时
 楼主| 发表于 2016-12-20 09:07:32 | 显示全部楼层
CallMeWater 发表于 2016-12-19 14:24
已关注,讲得很好,学习了

谢谢了
嵌入式开发微信公众号:嵌入式STM32软硬件开发
STM32交流,加好友,Q707372788
STM32交流群:383260480
回复 支持 反对

使用道具 举报

6

主题

33

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
491
金钱
491
注册时间
2020-8-3
在线时间
48 小时
发表于 2022-6-28 11:48:26 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 20:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表