我知道如何创建一个.map文件来跟踪错误消息包含实际地址时的访问冲突错误.
但是,如果错误消息说明了什么
Access violation at address 00000000. Read of address 00000000.
Run Code Online (Sandbox Code Playgroud)
我从哪里开始寻找这个问题的原因......?
Hea*_*utt 32
接受的答案并不能说明整个故事.
是的,无论何时看到零,NULL
都会涉及指针.这是因为NULL
是通过定义为零.所以叫零NULL
可能不是很多.
什么是你得到的消息有趣的是,其实NULL
提到两次.实际上,您报告的消息看起来有点像Windows品牌操作系统向用户显示的消息.
消息说地址 NULL
试图阅读 NULL
.那是什么意思呢?具体来说,地址如何自行读取?
我们通常会考虑在某个地址读取和写入内存的地址处的指令.知道这允许我们解析错误消息.该消息试图阐明地址处的指令试图阅读. NULL
NULL
当然,地址上没有指令NULL
,这就是我们NULL
在代码中认为特殊的原因.但是,每一条指令都可以被认为是从阅读本身的尝试开始.如果CPU EIP
寄存器位于地址NULL
,则CPU将尝试 从地址0x00000000()读取操作码以获取指令NULL
.此尝试尝试NULL
将失败,并生成您收到的消息.
在调试器中,EIP
当您收到此消息时,请注意等于0x00000000.这证实了我给你的描述.
接下来的问题是,"为什么我的程序会尝试执行NULL
地址." 我想到了三种可能性:
NULL
,从未初始化的函数指针进行函数调用,并且正在取消引用.NULL
在对象的vtable中有一个条目.这些是使用语法在代码中创建的virtual function_name()=0
.ret
指令时,NULL
将从覆盖的内存点加载值0x00000000().这种类型的错误,堆栈溢出,是我们论坛的同名词.既然你提到你正在调用第三方库,我将指出库可能是一种情况,期望你提供一个非NULL
函数指针作为某些API的输入.这些有时被称为"回叫"功能.
您将不得不使用调试器来进一步缩小问题的原因,但上述可能性应该可以帮助您解决问题.
你开始寻找你知道运行的代码附近,并且当你到达你知道没有运行的代码时就停止查找.
您正在寻找的可能是程序通过函数指针调用函数的某个地方,但该指针为空.
你也可能有堆栈损坏.您可能已将函数的返回地址覆盖为零,并且异常发生在函数的末尾.检查可能的缓冲区溢出,如果要调用任何DLL函数,请确保使用正确的调用约定和参数计数.
这不是使用空指针的常见情况,如未分配的对象引用或PChar.在这些情况下,您将具有非零"地址x "值.由于指令发生在地址0,因此您知道CPU的指令指针未指向任何有效指令.这就是为什么调试器不能告诉你哪行代码导致的问题-有是没有行的代码.您需要通过查找指向CPU跳转到无效地址的位置的代码来找到它.
调用堆栈可能仍然完好无损,这至少应该让您非常接近目标.但是,如果您有堆栈损坏,则可能无法信任调用堆栈.
归档时间: |
|
查看次数: |
107351 次 |
最近记录: |