我正在调试崩溃,我看到以下行为 -
当我将GDb附加到进程并执行信息寄存器时,我看到esp的以下值 -
esp 0xfd2475d0 0xfd2475d0
在崩溃的代码进行反汇编时,我看到以下内容 -
81c886a:c7 04 24 2c f9 8a 0c movl $ 0xc8af92c,(%esp)
如果我在/ proc // maps中查看地图文件,我会看到堆栈地址范围为 -
fff39000-fff59000 rwxp 7ffffffde000 00:00 0 [stack]
显然,GDB中ESP 0xfd2475d0的值与地图文件中的堆栈地址不同步。
这可能是崩溃的原因。我认为这应该是因为我得到了SIGSEGV。另外,我该如何解决这个问题?
请协助
答案 0 :(得分:0)
是的,这显然是分段错误的原因。实际上非常不明智,因为英特尔架构支持分配单独的代码,数据和堆栈段 - 并且所有内存访问(使用基址寄存器== ebp或esp)都隐式地通过堆栈段。
因为编译器将使用不同的基址寄存器(和不同的隐式段寄存器)来读取任何其他任意指针,这缩小了对堆栈寄存器损坏的搜索。
罕见的可能性是堆栈粉碎即。访问其他堆栈元素而不是当前函数作用域中的局部变量 - 在这种特殊情况下会破坏调用者的堆栈/帧指针。
void foo(int *p) {
int a[2];
a[4] = p;
}
更可能的选择是过度分配。
void foo() {
double too_big[6000000]; // this would be located at 0xfd......
int a; // this would be located at 0xfff3f000 ...
}