zhoujun19860612 发表于 2015-11-11 21:37:36

数组下标越界导致其他全局变量被窜改

最近一直被这问题困扰,今天才解决。
程序是跑在DSP28335上的,是串口接收另外一款处理器发来的数据,处理后发送给其他设备。
发现有时有些全局变量无缘无故被改变,而程序还在正常运行。感觉很奇怪,找了好几天问题,
后来发现是串口接收在处理异常报文时有bug,导致里串口接收缓存数组越界,然后越界后就将其他的变量给改变了。
用STM32时也遇到过数组越界,但这时候处理器是进硬件错误中断里了,没有像28335那样直接改变其他变量的,问下其他人有遇到过这种问题吗?
还有想请教下处理编程上注意外,其他还有什么办法防止数组下标越界吗?

Appcat 发表于 2015-11-11 21:47:31

FIFO环形队列,是治疗下标溢出的不二良药。

Appcat 发表于 2015-11-11 21:49:27

但是这个东西还是头疼医头脚疼医脚啊,
能解决造成溢出的根子才是正道

chenchaoting 发表于 2015-11-11 21:55:03

Appcat 发表于 2015-11-11 21:49
但是这个东西还是头疼医头脚疼医脚啊,
能解决造成溢出的根子才是正道

同问这个HardFault 芯片设计时是怎么检测越界的

lusson 发表于 2015-11-11 21:58:55

STM32也不见得会进hardFault,我就遇到过把我全局变量改了但不进的。
他进的话应该也是要非法访问才会的。

tim 发表于 2015-11-11 22:00:43

C语言不检查数组下标越界,如果应用中有越界的可能,就需要在程序中编写越界检查的代码

4058665 发表于 2015-11-11 22:08:41

必须要判断地址或者长度的      当然环形队列也是一种解决的方式
关键要根据接受数据的长度,选择适合的缓冲大小 ,帧数据到达后 即使处理即可以了   

dhbighead 发表于 2015-11-11 22:19:28

数组名不也是指针。。

10xjzheng 发表于 2015-11-11 22:29:21

也不是一定会进入硬件错误中断里面

lingdianhao 发表于 2015-11-11 22:33:46

我遇到过一次全局数组被意外修改的情况,后面采用数据访问断点调试发现是有个局部变量地址和全局变量重叠导致,编译器编译没有任何问题,上网查询,是因为栈空间设置太小导致,一直没明白这是为啥,不知道编译器是咋给变量分配地址的!!

usm4glx 发表于 2015-11-11 23:08:37

呵和,这个只能靠自己了

wangyan915205 发表于 2015-11-11 23:17:17

看来很有必要学习数据结构:

sywh 发表于 2015-11-12 08:47:44

变量如果在顺序存储的,你数组越界肯定导致后面的变量被意想不到的篡改。

10xjzheng 发表于 2015-11-12 09:01:18

lingdianhao 发表于 2015-11-11 22:33
我遇到过一次全局数组被意外修改的情况,后面采用数据访问断点调试发现是有个局部变量地址和全局变量重叠导 ...

这就是堆栈溢出啦

ts-fjw 发表于 2015-11-12 09:06:29

我也我也遇到 修改局部变量数组 结果改变全局变量数组了 一直没找到原因 似乎是局部变量数组太大的原因

ts-fjw 发表于 2015-11-12 09:07:38

lingdianhao 发表于 2015-11-11 22:33
我遇到过一次全局数组被意外修改的情况,后面采用数据访问断点调试发现是有个局部变量地址和全局变量重叠导 ...

怎么看局部变量和全局变量的地址

落叶知秋 发表于 2015-11-12 09:21:16

1.进入HardFault是因为非法访问了一些地址,比如说某些没有初始化的模块的地址;

2.单纯的数据RAM地址越界操作是不会进入HardFault的,至于为什么会修改全局变量,其实跟编译器编译出来的内存分配空间有关系;
比如说全局变量g_A、g_B、g_C是连续存放的,那么指向g_B的指针越界访问时,就会访问到g_C或g_A了,数组也是跟指针一样的道理;

3.要怎么防止这种地址越界?不要操作指针或者不要用C语言……如果做不到的话,就修炼编程能力吧

wujiaodalou911 发表于 2015-11-12 09:32:20

如果你的数组是局部变量你就把堆栈变大点,或者你把数组变成全局变量。

lingdianhao 发表于 2015-11-12 09:48:04

ts-fjw 发表于 2015-11-12 09:07
怎么看局部变量和全局变量的地址

MDK里面变量监视窗口里面添加变量名称,就会显示变量地址了。

ts-fjw 发表于 2015-11-12 10:49:48

lingdianhao 发表于 2015-11-12 09:48
MDK里面变量监视窗口里面添加变量名称,就会显示变量地址了。

哦 原来是这呀 一直只看数据了 从来没关心过地址谢谢

zhoujun19860612 发表于 2015-11-12 11:42:15

lusson 发表于 2015-11-11 21:58
STM32也不见得会进hardFault,我就遇到过把我全局变量改了但不进的。
他进的话应该也是要非法访问才会的。 ...

STM32也不一定进hardfault呀?我以前遇到数组越界就进了。
刚看了下stm32编译完后的.map文件,发现全局数组定义的地址,在数组需要的内存后还有一段内存是空着的,其他全局变量隔一段内存再定义的。在想stm32是不是通过检测这段空着的内存是否被访问来判断是否数组越界?

zhoujun19860612 发表于 2015-11-12 11:45:21

wujiaodalou911 发表于 2015-11-12 09:32
如果你的数组是局部变量你就把堆栈变大点,或者你把数组变成全局变量。

我数组就是全局的,越界后就会改变其他全局变量呀。
看dsp的.map文件,可以发展数组和其他全局变量都是挨着的,一旦数组越界就会访问到其他变量呀

zhoujun19860612 发表于 2015-11-12 11:46:15

chenchaoting 发表于 2015-11-11 21:55
同问这个HardFault 芯片设计时是怎么检测越界的


刚看了下stm32编译完后的.map文件,发现全局数组定义的地址,在数组需要的内存后还有一段内存是空着的,其他全局变量隔一段内存再定义的。在想stm32是不是通过检测这段空着的内存是否被访问来判断是否数组越界?

zhoujun19860612 发表于 2015-11-12 12:13:25

Appcat 发表于 2015-11-11 21:47
FIFO环形队列,是治疗下标溢出的不二良药。

环形队列没用过,研究下

zhoujun19860612 发表于 2015-11-12 12:17:07

dhbighead 发表于 2015-11-11 22:19
数组名不也是指针。。

存储方式不一样吧,数组定义完空间是固定了

侵掠如火 发表于 2015-11-12 15:40:04

本帖最后由 侵掠如火 于 2015-11-12 15:41 编辑

其实这就是C语言的美妙,所谓Stack Overflow.{:lol:}
这种问题主要靠功力来解决.
当然,UART缓冲区的话,环状缓冲区是常用选项.

HZKJ 发表于 2015-11-12 18:18:57

在程序里面做判断和限制啊

liuqian 发表于 2015-11-12 20:13:42

C里面数组一定要检查越界,不然一定死翘

maninblack 发表于 2015-11-12 21:17:24

chenchaoting 发表于 2015-11-11 21:55
同问这个HardFault 芯片设计时是怎么检测越界的

进HardFault原因很多,越界只是其中一种,猜测可能是检测到没有定义到的内存区域,比如代码compile时只用到1k ram,但是指针指到1k之外,就可以判定HarkFault错误了。
页: [1]
查看完整版本: 数组下标越界导致其他全局变量被窜改