如何知道谁修改了特定的内存(或者说变量)

ljpronaldo   2008-8-27 00:59 楼主
各位大虾:
问题是这样的:
我的程序里面有个变量,我发现他被修改成了一个不确定的值,但是按照正常的程序运行,这个变量不可能变成这个值,应该是被其他的task错误地修改了。
所以我想是否有这样的技术:
我想当某一块内存(或者说是变量)被修改的时候调用一个函数,我可以在这个函数里面记录是谁在修改这个变量,这样我就可以知道到底是谁错误的修改了这个变量。但是我不希望使用硬件断点让程序停下来,因为停下来后正确的操作也无法进行了。
多谢啦!

回复评论 (19)

找到那个变量在的所有地方,加上打印就可以了!
点赞  2008-8-27 11:34
我试过了,正常访问的地方不会出现这种情况,所以我怀疑应该是有什么地方的指针指飞掉了,就写到了这个变量这里来。。。
点赞  2008-8-27 16:20
比较头痛的问题,你试试在这个变量前面定义一个int数组,然后监视该数组的内容有没有变化!
点赞  2008-8-27 22:38
任务栈的内存空间分配一般来说按任务启动的顺序来分配的,是相邻的任务对就的栈也相邻,例如:任务A、任务B、任务C启动的先后顺序依次是:taskSpawn(A)->taskSpawn(B)->taskSpawn(C),则它们对应的任务栈通常也是A->B->C,如果B的栈空间写坏了,最大的嫌疑是A任务中的某个函数,你最好查查任务A中所有的MEMCPY()的地方,或者是数组赋值的地方,有没有引起下标越界,或下标减成负数的情况。。。

祝好运!!
点赞  2008-8-27 23:07
加断点,好像有那种变量改变就停的断点。
点赞  2008-8-30 00:14
哥们,强烈建议用勾子函数,查查taskSwitchHookAdd函数的用法吧,在钩子函数里面比较变量
这样可以确定是哪个人物在那个taskDelay中改变了参数,因为一般都是memcopy,bcopy,memset,bfill,改变的,还有一个不容易发现的问题就是数组下标越界
编写好这个函数以后差错很有用的.
点赞  2008-8-30 20:17
楼上的正解,通常都会这样来定位内存越界
点赞  2008-9-4 15:23
数据断点不是最简单的么?
干吗那么费事阿
点赞  2008-9-4 17:02

这种技术还没听说过,

不过以前碰到过某块地址会产生exception的情况,就是利用mmu把这块地址保护起来,写的时候就会产生exception!!!不过只能保护连续的一块地址。
点赞  2008-9-7 10:12
貌似数据断点需要硬件支持的吧?

如果处理器支持硬件数据断点,而且调试工具又支持这一特性的话,可以考虑用这个功能。

楼上用MMU来触发exception,然后根据exception的信息来处理,也是不错的主意
点赞  2008-9-18 11:52
我所知道的最好办法就是:
挂个钩子函数taskSwitchHookAdd,钩子函数很简单,申请一个相当大的内存,只记录2个东西,希望监控的地方的内存的值和任务ID
一旦内存出现错误值,则查看是什么任务造成的,然后再去查看这个任务。
看任务哪里会修改内存值,就需要看具体情况了。
点赞  2008-9-18 20:19
钩子函数最好用,写好一个永久受用。
强烈推荐,牙好,胃口就好。
嵌入式开发中更多的情况是查错误,产品功能性的错误是需求和设计中已经定义的,出了错看看需求就是了,解决起来容易,主要就是沟通;系统框架的问题一般不容易出错;在开发过程最常见的错误(尤其我们现在在vxworks下大多用C进行开发),由指针引发的地址“溢出”错误是最常见的,也是最难以发现的。
点赞  2008-9-24 11:16
最好查下硬件内存映射分配是否冲突。

冲突的话,即时软件怎么运行也不好定位问题,因为大家约定的就是访问那个地址。
点赞  2008-9-28 12:16
bh硬断点
点赞  2008-11-1 10:04
引用: 引用 6 楼 coolwysergmail 的回复:
哥们,强烈建议用勾子函数,查查taskSwitchHookAdd函数的用法吧,在钩子函数里面比较变量
这样可以确定是哪个人物在那个taskDelay中改变了参数,因为一般都是memcopy,bcopy,memset,bfill,改变的,还有一个不容易发现的问题就是数组下标越界
编写好这个函数以后差错很有用的.


好主意.
点赞  2008-11-20 11:13
主要两种方法:
1.任务切换中对其进行检查并记录破坏的任务id,大部分能定位出哪个任务进行破坏的;
2.如果地址是固定的(且数据不经常被修改),可以考虑采用数据断点的方式;
以上两种方法对越过CPU的破坏(如DMA等)无能为力;

这种属于相对简单的野指针破坏,其他80%的问题都是前面的数据越界破坏;
点赞  2008-12-30 13:32
我想当某一块内存(或者说是变量)被修改的时候调用一个函数,我可以在这个函数里面记录是谁在修改这个变量,这样我就可以知道到底是谁错误的修改了这个变量。但是我不希望使用硬件断点让程序停下来,因为停下来后正确的操作也无法进行了。

---如果要实现这样的话,也可以,需要接管数据访问异常向量的处理函数,如果发现是需要修改的地址,直接修改后返回就可以了。异常在返回后会重新执行失败的那条指令。
点赞  2008-12-30 13:34
引用: 引用 17 楼 erigido 的回复:
我想当某一块内存(或者说是变量)被修改的时候调用一个函数,我可以在这个函数里面记录是谁在修改这个变量,这样我就可以知道到底是谁错误的修改了这个变量。但是我不希望使用硬件断点让程序停下来,因为停下来后正确的操作也无法进行了。

---如果要实现这样的话,也可以,需要接管数据访问异常向量的处理函数,如果发现是需要修改的地址,直接修改后返回就可以了。异常在返回后会重新执行失败的那条指令。


没明白你的意思?如果有数据硬件断点功能,程序停下来后,你可以通过当前的PC指针知道究竟程序是怎么修改你的数据的,可以知道究竟是合法操作还是程序出错的原因导致数据被修改。

我不知道你说的“因为停下来后正确的操作也无法进行了”是啥意思,断点只是让程序暂停而已,你可以继续执行的。暂停的目的只是为了可以观察程序运行上下文。
点赞  2008-12-31 12:29
引用: 引用 6 楼 coolwysergmail 的回复:
哥们,强烈建议用勾子函数,查查taskSwitchHookAdd函数的用法吧,在钩子函数里面比较变量
这样可以确定是哪个人物在那个taskDelay中改变了参数,因为一般都是memcopy,bcopy,memset,bfill,改变的,还有一个不容易发现的问题就是数组下标越界
编写好这个函数以后差错很有用的.

按楼主的说法,这个变量不是按照正常的流程去修改的,所以用钩子去看memcopy等函数不一定能够找到结果,也可能是溢出之类的行为造成的。
点赞  2008-12-31 12:37
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复