powerall888
驱动小牛
驱动小牛
  • 注册日期2007-03-02
  • 最后登录2010-09-29
  • 粉丝0
  • 关注0
  • 积分906分
  • 威望329点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
阅读:1098回复:7

只要系统进入过睡眠状态,这段代码就不能工作,为什么?

楼主#
更多 发布于:2007-03-22 16:02
  2440平台上我有一个测试应用程序通过按下一个按钮执行下面一段代码:

    DWORD *timeout_ptr;
    timeout_ptr = (DWORD *)VirtualAlloc(0, 4096, MEM_RESERVE, PAGE_NOACCESS);    
    if (!VirtualCopy((PVOID)timeout_ptr, (PVOID)(0xB2000000), 4096, PAGE_READWRITE|PAGE_NOCACHE)) {    
        return ;
    }    
    DWORD* test_ptr=(DWORD*)((BYTE*)timeout_ptr+(*(timeout_ptr+0x07)));
    *(test_ptr+0x00)=20;
    *(test_ptr+0x01)=30;
    *(test_ptr+0x02)=40;

在系统从来没有进入睡眠状态时,此代码能够正常工作。
可以只要系统曾经进入过睡眠状态,这段程序就不能正常工作,弹出如下错误对话框:

    应用程序GPIOTest.exe执行了一个非法操作,将被关闭...
        程序:GPIOTest.exe
        异常:0x80000002
        地址:038AAFA4

请问这是为什么?
powerall888
驱动小牛
驱动小牛
  • 注册日期2007-03-02
  • 最后登录2010-09-29
  • 粉丝0
  • 关注0
  • 积分906分
  • 威望329点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-03-22 16:18
该问题似乎可以转变为另一个问题:如果系统睡眠过,则通过VirtualAlloc,VirtualCopy等函数映射后访问某段内存时都会出错;如果在系统睡眠前都已经映射完成了,则可以避免这个问题。
zhoumc
驱动牛犊
驱动牛犊
  • 注册日期2006-07-13
  • 最后登录2008-11-25
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望88点
  • 贡献值0点
  • 好评度80点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-03-22 18:25
DWORD* test_ptr=(DWORD*)((BYTE*)timeout_ptr+(*(timeout_ptr+0x07)));
这一句中,有点问题:timeout_ptr+0x07这个地址空间内的内容并未见初始化,而且timeout_ptr是DWORD *型,如果该空间内的值是任意的,则test_ptr可能已经超出你申请的地址空间了,每次把
(*(timeout_ptr+0x07))的值打出来看看。
wenzai
驱动中牛
驱动中牛
  • 注册日期2002-04-16
  • 最后登录2011-03-04
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望424点
  • 贡献值0点
  • 好评度309点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-03-22 18:48
不能用系统调用吧
powerall888
驱动小牛
驱动小牛
  • 注册日期2007-03-02
  • 最后登录2010-09-29
  • 粉丝0
  • 关注0
  • 积分906分
  • 威望329点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-03-22 19:14
“不能用系统调用吧” --- 什么意思?

timeout_ptr+0x07地址没错,他对应的地址就是0xb2000000+7*4,就是0xb200001c
zhoumc
驱动牛犊
驱动牛犊
  • 注册日期2006-07-13
  • 最后登录2008-11-25
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望88点
  • 贡献值0点
  • 好评度80点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-03-22 22:25
timeout_ptr+0x07是0xb200001c,这点没错。但你用(*(timeout_ptr+0x07)),取得是该地址中存的值,再将该值与timeout_ptr相加,不知你在其它地方是否对该地址进行了初始化,如果是任意值,则
*(test_ptr+0x00)=20;
可能越界
powerall888
驱动小牛
驱动小牛
  • 注册日期2007-03-02
  • 最后登录2010-09-29
  • 粉丝0
  • 关注0
  • 积分906分
  • 威望329点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-03-23 08:34
此处赋初值了,就像相对地址0xb2000000的偏移量.

如果没有睡眠过的话,这段代码是没有任何错误的。
如果睡眠过,就有问题了
zhoumc
驱动牛犊
驱动牛犊
  • 注册日期2006-07-13
  • 最后登录2008-11-25
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望88点
  • 贡献值0点
  • 好评度80点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-03-23 08:55
0xb2000000在你的设备中是什么内存的地址
游客

返回顶部