无法跟踪访问冲突0xC00000FD

时间:2009-11-01 14:56:07

标签: c++ stack-overflow

我正在使用VS2008,我的MFC应用程序在设置断点或运行到光标时已经开始崩溃。我收到很多这样的错误: -

First-chance exception at 0x78a5727c (mfc90ud.dll) in MyApp.exe: 0xC0000005: Access violation reading location 0xfffffffc.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.

调用堆栈不是很多,它只列出NT.dll中的代码

>   00000000()  
    ntdll.dll!7c9032a8()    
    [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] 
    ntdll.dll!7c90327a()    
    ntdll.dll!7c92aa0f()    
    ntdll.dll!7c90e48a()    
    ntdll.dll!7c9032a8()    

我无法使用断点或单步执行代码来查找问题。如果在VS中使用F5运行,应用程序“似乎”正常运行。

什么是追踪此问题的最佳方法?

4 个答案:

答案 0 :(得分:5)

问题标题中的堆栈溢出在哪里?访问冲突通常表示指针取消引用无效。

使用修订历史记录查找事情开始的第一个版本 boom ,然后批判性地分析在该修订版中修改的代码内部和周围发生的所有指针内容。

答案 1 :(得分:2)

我会使用我的通灵调试技巧并告诉你,你正在覆盖堆栈中的缓冲区 - 具体来说,你正在写一个不够大的缓冲区写入太多的零。

你有一个被破坏的堆栈的经典症状 - 你遇到的第一个AV试图访问零减去几个字节 - 显然是你的堆栈指针偏移到你的参数或你的局部变量。 (我永远不会记得哪些是在堆栈指针之上,哪些是在下面。)然后你有一堆行指示指令指针已被设置为零,这经常发生,因为堆栈帧中的函数返回地址有被零值覆盖 - 因为你覆盖了基于堆栈的缓冲区并破坏了堆栈中所有其他重要的东西。当你的程序试图从当前函数返回时,它会在堆栈中查看它认为它来自何处,看到零,然后在那里跳转。糟糕!

由于您的堆栈被删除,您可能无法发现堆栈跟踪太有用;这一点你的堆栈帧可能会被破坏。

答案 2 :(得分:2)

网络上有一些用于制作Windows程序的“模板” 而不是在WndProc()

case WM_CLOSE:
     PostQuitMessage(SUCCESS);
     break;
case WM_DESTROY:
    DestroyWindow(hwnd);
    break;

我们得到了这个:

case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
case WM_DESTROY:
    PostQuitMessage(SUCCESS);
    break;

如果SUCCESS为0,DestroyWindow()将获得一个产生异常的空指针 当窗户关闭时。

答案 3 :(得分:0)

Visual Studio有一个选项可以在第一次机会异常时中断(不记得确切的位置,可能是调试子菜单中的异常菜单项?)你想打开它并查看你的调用堆栈的那一刻他们发生了。

还有一个选项可以打开Microsoft Symbol Server,它会自动下载您在堆栈中看到的任何系统dll的匹配符号。 (对不起,不记得究竟是怎么设置的。)