0

我正在使用 VS2008 调试 GPF(访问违规)。将 EIP 设置为崩溃地址,它会及时弹出我的一些源代码。这似乎不是 GPF 的原因。

我在一台8核机器上。这些东西上是否有多个 CS:EIP 寄存器?如果是这样,我如何在 Visual Studio 中访问它们?

非常感谢!

4

2 回答 2

1

一般保护错误 (GPF) 可能由任何类型的无效内存访问引起。不仅通过尝试在无效内存地址上执行指令,还通过尝试访问指令使用的无效内存地址上的操作数。例如,

mov [eax], ebx

如果存储在 eax 中的值为 NULL(经典的空指针解引用),将导致 GPF。如果 Visual Studio 调试器将您指向某个特定的指令地址 (CS:EIP),并且您可以在该地址上找到代码,则故障原因将是该指令使用的内存操作数的地址。默认情况下,Visual Studio 将在错误线程的上下文中为您提供信息。因此,没有任何理由去查看另一个线程上下文。

例如: 在此处输入图像描述

如果我们然后打开 Debug->Windows->Disassembly,我们将看到下一张图片: 在此处输入图像描述

如您所见,GPF 是由 eax 中存储的无效地址引起的。第一张图消息框中指示的错误指令地址 0x012b1002 与第二张图上的调试器指向的相同。第一张图片中的错误地址 0x00000000 是存储在 eax 中的地址,并用作 mov 指令中的内存定位参数。

于 2012-12-06T06:37:02.753 回答
0

如今,每个内核都有两套完整的寄存器,包括 CS:EIP,尽管在 64 位时代 CS 并不重要。两个是因为超线程(一个物理内核中的两个虚拟内核,或多或少)。但是每组寄存器都是独立的,你不会受到不同进程的干扰(除非你的操作系统真的很糟糕)。

至于你的问题。GPF 很棘手,它可能看起来不像问题出在调试器所说的那样,但相信它的话通常是件好事。您的程序中可能存在内存问题、错误的指针、溢出、悬空指针、未初始化的变量或类似的事情。如果您使用 Linux,我会说尝试 valgrind。如果您的应用程序是多线程的,那么所有这些都会变得更糟。

您的问题中没有足够的信息,但我建议您卷起袖子进行调试。例如添加一堆断言或变量记录。

于 2014-01-21T08:32:20.920 回答