我目前正在调查 Windows 崩溃转储,Visual Studio 调试器在打开转储文件时向我显示“非法指令 0xC000001D
”。它显示此错误的代码位置显示了以下示例的反汇编:
void g(int x) {
00401E80 push ebp
00401E81 mov ebp,esp
if(x > 20) {
00401E83 cmp dword ptr [x],14h
00401E87 jle g+14h (401E94h)
x *= 4;
>00401E89 db 0fh // illegal instruction here
00401E8A db 0fh
00401E8B xadd eax,esp
00401E8E add cl,byte ptr [ecx+9EB0845h]
x += 42;
00401E94 mov ecx,dword ptr [x]
...
我通过在调试器内存窗口中用一些无效值覆盖函数代码,在调试器中手动创建了上述示例,但我正在调查的故障转储显示相同的 db 0fh
条目,显然表明无效指令。该代码也类似于我的转储文件显示的内容,因为无效指令之前的指令似乎都是有效的并且与源代码匹配。
现在的问题是 是否有可能在正常编译的 C++ 程序中 - 不会混淆内存页面访问限制 -(Windows XP 上的 Visual C++ 2005)上进程的代码段?
如果我尝试从代码写入上面示例中的函数地址,我总是会遇到访问冲突,即代码段内存页似乎被写保护。
{
void* fnAddr = &g; // non-portable but OK in VC++
unsigned int x = 0xDEADBEEF;
// Simulate memory corruption: Try to write something to the code segment:
memcpy((char*)fnAddr+4, &x, sizeof(x)); // generated 0xC0000005 Access Violation
g(42); // call messed up function - never get here
}
您是否知道实际上有可能无意中覆盖代码段中某些内容的任何情况?
我应该补充一点,真正的程序要复杂得多,有很多虚函数,一些成员函数指针等等,遗憾的是这个问题是不可重现的,我们目前只有这个看起来不错的转储文件. -- 尽管如此,转储文件在代码段中显示了一条非法指令,我不认为可能会弄乱代码段。
最佳答案
不,包含代码的内存页是写保护的。这种损坏只能发生在进程初始化时。但更可能的来源是软 RAM 错误。请您的客户运行 RAM 测试程序。考虑文件损坏是错误是可重复的。
关于c++ - 是否可以在Windows XP下用普通的C++程序覆盖代码段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4248170/