【问题标题】:What is meaning of write at zero after method call?方法调用后写为零是什么意思?
【发布时间】:2014-05-21 10:30:46
【问题描述】:

我在共享库中有一个 sigfault。有一个堆栈跟踪。

(_bad_func+0x3dd)

函数定义为:

000000000008b030 <_bad_func>:

我找到了问题所在(0x08b950 + 0x3dd => 0x8bd2d)并感到困惑。

   8bd23:   bf 03 00 00 00          mov    $0x3,%edi
   8bd28:   e8 03 ca fe ff          callq  78730 <sleep@plt>
   8bd2d:   c6 04 25 00 00 00 00    movb   $0x0,0x0
   8bd34:   00 
   8bd35:   e9 3a ff ff ff          jmpq   8bc74 <xxx+0x324>

我认为“movb $0x0,0x0”总是失败。它将 0 文字写入 nullptr。 为什么编译器把它放在这里?睡眠功能是非常常见的系统之一。 我猜它不会触及它的返回地址。所以 100% 在它休眠 3 秒后 进程收到段错误。

如果存在用于对齐下一条指令的存根字节,为什么它们不只是零(或 1 字节指令 NOP = 90)。

这是英特尔 elf64 代码。

_bad_func 在 gdb 中看起来是一样的。

gdb proc
br xxx   # stop and at the func after library initialized
start
disas _bad_func

   0x00002aaaaaf5dd23 <+979>:   mov    $0x3,%edi
   0x00002aaaaaf5dd28 <+984>:   callq  0x2aaaaaf4a730 <sleep@plt>
   0x00002aaaaaf5dd2d <+989>:   movb   $0x0,0x0
   0x00002aaaaaf5dd35 <+997>:   jmpq   0x2aaaaaf5dc74 <xxx+804>

【问题讨论】:

  • 为什么编译器把它放在这里? - 也许共享库有一个错误的语句/语句序列可以转换成这个?
  • 这是一个未解析的外部变量。是来自objdump -d 吗?试试objdump -r -R -d

标签: gcc assembly intel disassembly


【解决方案1】:

这可能是库发出致命错误信号的方式——故意崩溃。或者,可能,零是可重定位地址的占位符,应该由加载程序修补。尝试使用重定位信息进行反汇编:

objdump -dr libmylib.so

我建议不要尝试通过反汇编来追踪问题,而是使用调试器,例如gdb。它将向您显示故障的确切位置,以及运行时的实际指令(不是占位符)。

顺便说一句,你的数学是错误的。 0x8B030 + 0x3DD 就是 0x8B40D。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 2015-01-22
    • 1970-01-01
    • 2022-04-18
    • 2013-03-29
    • 2013-01-30
    • 1970-01-01
    相关资源
    最近更新 更多