硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1479|回复: 9
收起左侧

[技术讨论] IAR u8变量被莫名奇妙清零【已破案,原因在于指针越界写操作】

[复制链接]

78

主题

278

回帖

512

积分

金牌会员

积分
512
发表于 2024-9-1 23:12:30 | 显示全部楼层 |阅读模式
本帖最后由 logo 于 2024-9-2 22:03 编辑

   微信截图_20240901225850.jpg



STM32F407VET6 IAR 开到 High Size优化,发现定义的一个unsigned char 变量会被后面程序的运行莫名奇妙的改变值。导致程序逻辑错误,打了断点调试很久浪费了一天时间才发现异常点。改成u32就好了。
程序有大小限制,因此不方便不开Size优化的情况下测试。目前暂时只能改为u32运行。不知道和High Size优化有没有关系。暂时没时间研究了,这里先记录下这个问题。后面有空研究下。



回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-9-2 08:41:00 | 显示全部楼层
方便的时候把代码也分享下,无码无真相。
回复

使用道具 举报

78

主题

278

回帖

512

积分

金牌会员

积分
512
 楼主| 发表于 2024-9-2 09:39:23 | 显示全部楼层
eric2013 发表于 2024-9-2 08:41
方便的时候把代码也分享下,无码无真相。

只节选了出问题部分的代码。

[C] 纯文本查看 复制代码
void fun(void)
{
//static u8 i=0;
static u32 i=0;
if(i==0)
{
i=1;
}

……
程序在走完以上if条件判断语句以后,i应该一直为1,但奇怪的问题在这里发生了。

i定义为u32程序功能逻辑正常。
定义为u8,i的值会被莫名其妙清零,导致反复进入if条件里的语句,导致程序逻辑功能异常。
省略号部分程序并没有操作i变量的代码。

……

}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-9-2 10:09:30 | 显示全部楼层
logo 发表于 2024-9-2 09:39
只节选了出问题部分的代码。

[mw_shl_code=c,true]void fun(void)

这个不能说明问题。
回复

使用道具 举报

8

主题

65

回帖

89

积分

初级会员

积分
89
发表于 2024-9-2 12:24:50 来自手机 | 显示全部楼层
试试这样子volatile static u8 i=0;看看和static u32 i=0;效果是否一样?可能就是优化与数据对齐的问题。
回复

使用道具 举报

0

主题

290

回帖

290

积分

高级会员

积分
290
发表于 2024-9-2 13:57:18 | 显示全部楼层
定义成个4个uint8_t 的数组,然后看看被改变的有哪几个。
回复

使用道具 举报

49

主题

385

回帖

532

积分

金牌会员

积分
532
发表于 2024-9-2 15:27:27 | 显示全部楼层
你试试打数据断点呢(写操作)?看能不能抓到
回复

使用道具 举报

78

主题

278

回帖

512

积分

金牌会员

积分
512
 楼主| 发表于 2024-9-2 19:24:45 | 显示全部楼层
lb1057907736 发表于 2024-9-2 12:24
试试这样子volatile static u8 i=0;看看和static u32 i=0;效果是否一样?可能就是优化与数据对齐的问题。

volatile和4字节对齐都试过没有用。目前只能采用u32方法,暂时没精力深究这个具体原因
回复

使用道具 举报

78

主题

278

回帖

512

积分

金牌会员

积分
512
 楼主| 发表于 2024-9-2 19:30:36 | 显示全部楼层
wanglehui_12 发表于 2024-9-2 15:27
你试试打数据断点呢(写操作)?看能不能抓到

具体 i 的值被异常清零的代码部分有for循环需要循环很多次,看现象是for循环执行完毕以后i的值被改变,具体第几次for循环改变的值还没有跟踪,晚点跟踪看下。


目前思路是在for循环中判断该 i 变量的值是否为0,一旦为零则断点停下。然后再顺藤摸瓜找原因。

回复

使用道具 举报

78

主题

278

回帖

512

积分

金牌会员

积分
512
 楼主| 发表于 2024-9-2 22:02:16 | 显示全部楼层
wanglehui_12 发表于 2024-9-2 15:27
你试试打数据断点呢(写操作)?看能不能抓到

刚才花了两个小时跟踪代码,发现并解决问题了。

问题原因在于:指针操作越界


在这个函数里还定义有数组u8 arry[1024];
跟踪了下发现定义的static u8 i=0;被编译器刚好安排在紧跟着数组arry的末尾地址。


后续程序有部分是网上下载的代码,细节没研究,研究后发现存在指针操作写数组arry的时候指针地址超过了数组arry的地址。于是把i变量所在地址的值给意外改写了。


这里解释下为什么定义为static u32 i=0;就不会被意外改写,原因是当定义为u32时候发现编译器把i的地址安排的和arry数组末尾的地址不挨着。所以i的值不会被意外改写。



回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 02:45 , Processed in 0.046972 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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