代码之家  ›  专栏  ›  技术社区  ›  Stéphane

如何将segfault指令指针地址从/var/log/messages映射到.map文件中的地址/函数?

  •  2
  • Stéphane  · 技术社区  · 15 年前

    (我的环境是64位Ubuntu,我的应用程序是C++编译的,用G++连接的。)

    当应用程序执行诸如除以零或运行 asm("int $3") 保留在代码中,通过syslog将以下内容之一记录到 /var/log/kern.log /var/log/messages :

    Sep 10 18:06:47 VM kernel: [117194.123452] a.out[20288] trap divide error ip:45c59d sp:7fff65a91810 error:0 in a.out[400000+144000]
    Sep 10 18:07:10 VM kernel: [117217.020833] a.out[20294] trap int3 ip:45c493 sp:7fff5cc559f0 error:0
    

    在这两种情况下,指令指针地址都指向我可以在 .map 链接时生成的文件(使用“ -Wl,-Map,output.map “”。

    但如果我导致SEG故障,在这种情况下,通过呼叫 memcpy() 当源设置为空时,指令指针超出范围,我不知道应该如何映射它:

    Sep 10 18:06:13 VM kernel: [117160.228587] a.out[20282]: segfault at 0 ip 00007f7e79209092 sp 00007fff831faf08 error 4 in libc-2.9.so[7f7e79185000+168000]
    

    在这个例子中,我希望IP在0x445e70-0x445e7f的范围内,根据我的.map文件,这是memcpy()的位置。

    我的问题:在这种情况下,解释IP的诀窍是什么?

    1 回复  |  直到 15 年前
        1
  •  3
  •   mark4o    15 年前

    根据消息,它看起来像是坠毁在里面了 memcpy() ,从 libc-2.9.so ,它映射到您的进程,从0x7f7e79185000开始。这应该是因为 memcpy 正试图取消对指针的引用的函数。指令指针看起来有效,因为它在libc的范围内。如果您打算重写memcpy并调用自己的版本,则可能需要使用 -fno-builtin-memcpy .

    编辑: 您可能静态地链接libc,但是根据消息,您还将libc共享库映射到您的进程内存中。你应该看到它列在 /proc/ PID /maps 程序运行时。可能是您正在链接另一个共享库,如libstdc++,它依赖于libc共享库。因此,您有两个版本的memcpy,在这种情况下,它将调用libc共享库版本,该版本映射在高位地址。如果不需要libc共享库,请确保链接 全部的 静态库;使用 -static 链接行开始处的选项。