ESP 出现段错误超出 /proc/pid/maps 中的 [stack] 范围?

问题描述 投票:0回答:1

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

当我将 GDB 附加到进程并执行信息寄存器时,我看到 esp 的以下值 -

esp            0xfd2475d0       0xfd2475d0

在对崩溃的代码进行反汇编时,我发现它正在存储到堆栈指针指向的内存中 -

81c886a:       c7 04 24 2c f9 8a 0c    movl   $0xc8af92c,(%esp)

如果我在

/proc/<PID>/maps
中查看映射文件,我会看到堆栈地址范围为 -

fff39000-fff59000 rwxp 7ffffffde000 00:00 0                              [stack]

显然,GDB中

ESP 0xfd2475d0
的值与maps文件中的堆栈地址不同步。

这可能是崩溃的原因吗?我认为这应该是因为我收到 SIGSEGV。另外,我该如何解决这个问题?

assembly x86 crash stack-overflow stack-memory
1个回答
-1
投票

是的,这显然是分段错误的原因。不抛出它实际上是非常不明智的,因为英特尔架构支持分配单独的代码、数据和堆栈段——并且所有内存访问(基址寄存器== 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 ... 
 }
© www.soinside.com 2019 - 2024. All rights reserved.