ESP 在 /proc/pid/maps 和二进制文件中不同
Posted
技术标签:
【中文标题】ESP 在 /proc/pid/maps 和二进制文件中不同【英文标题】:ESP different in /proc/pid/maps and binary 【发布时间】:2012-12-27 08:19:38 【问题描述】:我正在调试崩溃,我看到以下行为 -
当我将 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 [堆栈]
显然,GDB 中 ESP 0xfd2475d0 的值与映射文件中的堆栈地址不同步。
这可能是崩溃的原因吗?我认为这应该是因为我正在获得 SIGSEGV。还有,这个问题怎么解决?
请帮忙
【问题讨论】:
【参考方案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 ...
【讨论】:
请注意,主流操作系统不使用分段,因此它们不会捕获指定堆栈区域之外的访问(仅适用于通常的内存保护)。如果您使用线程或 sigaltstack,这一点很重要,在这种情况下,其他一些内存块用作堆栈。以上是关于ESP 在 /proc/pid/maps 和二进制文件中不同的主要内容,如果未能解决你的问题,请参考以下文章
/proc/$pid/maps 在 x86_64 linux 上显示没有 rwx 权限的页面