2

(我的环境是 64 位 Ubuntu,我的应用程序是 C++ 编译并与 g++ 链接。)

当应用程序执行诸如除以零或asm("int $3")在代码中运行 left 之类的操作时,以下内容之一将通过 syslog 记录到/var/log/kern.logand /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”)。

但是,如果我导致段错误,在这种情况下,通过调用memcpy()将源设置为 NULL,指令指针超出范围,我不知道它应该如何映射:

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 的技巧是什么?

4

1 回答 1

3

根据消息,它看起来像是memcpy()libc-2.9.so0x7f7e79185000 开始映射到您的进程的内部崩溃。这是意料之中的,因为memcpy这是试图取消引用指针的函数。指令指针看起来有效,因为它在 libc 的范围内。如果您打算覆盖 memcpy 并调用您自己的版本,则可能需要使用-fno-builtin-memcpy.

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

于 2009-09-11T04:12:21.943 回答