ESP在/ proc / pid / maps和二进制文件中有所不同

时间:2012-12-27 08:19:39

标签: assembly crash gdb core

我正在调试崩溃,我看到以下行为 -

当我将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。另外,我该如何解决这个问题?

请协助

1 个答案:

答案 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 ... 
 }