Linux 运行ltrace时没有输出
正如标题所说,ltrace在我的系统上不能正常工作。 它在大多数情况下不显示输出,如Linux 运行ltrace时没有输出,linux,ubuntu,shared-libraries,ltrace,Linux,Ubuntu,Shared Libraries,Ltrace,正如标题所说,ltrace在我的系统上不能正常工作。 它在大多数情况下不显示输出,如 $ltrace ls [usual ls output] +++ exited (status 0) +++ $gcc hello.c $ltrace ./a.out Hello world! +++ exited (status 0) +++ 我使用的是最新的ltrace版本(来自package0.7.3-5.1ubuntu4),我甚至尝试从源代码重新编译,没有任何区别。 我正在使用Ubuntu16.10
$ltrace ls
[usual ls output]
+++ exited (status 0) +++
$gcc hello.c
$ltrace ./a.out
Hello world!
+++ exited (status 0) +++
我使用的是最新的ltrace版本(来自package0.7.3-5.1ubuntu4
),我甚至尝试从源代码重新编译,没有任何区别。
我正在使用Ubuntu16.10
,内核4.8.0-42-generic
。gcc版本为6.2.0
奇怪的是,从互联网下载的二进制文件似乎可以正常工作,正确地显示了库调用
我错过了什么?有人能重现这个问题吗?这可能与现在使用
-z
编译二进制文件有关。我创建了一个快速测试程序(我使用的是Ubuntu 16.04):
如果我使用gcc-O2 test.c-o test
编译它,那么ltrace可以工作:
$ ltrace ./test
__libc_start_main(0x400430, 1, 0x7ffc12326528, 0x400550 <unfinished ...>
write(0, "hello\n", 6hello
) = 6
+++ exited (status 0) +++
您可以使用Ubuntu上的pax-utils
包中的scanelf
检查二进制文件是否是这样编译的:
$ scanelf -a test*
TYPE PAX PERM ENDIAN STK/REL/PTL TEXTREL RPATH BIND FILE
ET_EXEC PeMRxS 0775 LE RW- R-- RW- - - LAZY test
ET_EXEC PeMRxS 0775 LE RW- R-- RW- - - NOW test2
请注意,LAZY
(ltrace起作用)与现在的(ltrace不起作用)相比
这里还有一点讨论(但没有解决方案):
简短的回答是ltrace
由于被跟踪二进制文件的对象文件类型和位置独立的可执行文件,其行为不符合预期。如果正在跟踪的二进制文件具有ET_EXEC
对象文件类型且没有位置独立的可执行文件,则ltrace
将能够拦截并记录动态库调用
有关二进制文件的对象文件类型(ET_EXEC
,ET_DYN
等),请参阅(0x10偏移)
为了验证这一点,我将使用与前面答案相同的test.c
程序:
#包括
int main(){
写入(0,“hello\n”,6);
返回0;
}
我的系统符合/etc/os发行版:
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
默认gcc-v
(版本和配置):
现在使用gcc test.c-o test
编译,我们有:
$ ltrace ./test
hello
+++ exited (status 0) +++
$ ltrace ./test
write(0, "hello\n", 6hello
) = 6
+++ exited (status 0) +++
使用readelf-h./test | grep Type
检查二进制文件的对象文件类型:
Type: DYN (Shared object file)
Type: EXEC (Executable file)
使用强化检查检查检查位置独立可执行文件。/test|grep Position
:
Position Independent Executable: yes
Position Independent Executable: no, normal executable!
然而,使用gcc-no pie test.c-o test进行编译时,我们有:
$ ltrace ./test
hello
+++ exited (status 0) +++
$ ltrace ./test
write(0, "hello\n", 6hello
) = 6
+++ exited (status 0) +++
使用readelf-h./test | grep Type
检查二进制文件的对象文件类型:
Type: DYN (Shared object file)
Type: EXEC (Executable file)
使用强化检查检查检查位置独立可执行文件。/test|grep Position
:
Position Independent Executable: yes
Position Independent Executable: no, normal executable!
希望这有助于澄清ltrace
的行为及其与跟踪的二进制文件的对象文件类型和位置无关的可执行文件的关系。我可以在16.10上复制,其中gcc已配置为默认生成饼图可执行文件。根据它的变更日志,ltrace从0.7.0开始就支持PIE可执行文件,所以我不确定0.7.3版为什么不工作。解决方法是使用--无饼图
编译程序,尽管这会降低安全性一点(ASLR仍将对共享库启用,但不会对可执行文件启用)。@MarkPlotnick我尝试使用--无饼图
编译程序,不幸的是<代码>--运气不好
:)还是一样的问题。即使成功了,我仍然不明白为什么没有追踪到/bin/ls&Co。既然您能够复制,我就在ltrace-devel邮件列表上发布了,让我们看看是否有人能解决这个奇怪的问题。@MarkPlotnick我错了<代码>--没有饼
单独给我错误重新定位R_X86_64_32。创建共享对象时不能使用rodata;用-fPIC
重新编译,所以我想我应该按照建议用-fPIC
重新编译。。。太糟糕了,这仍然会产生馅饼。所以,我想你的解释是对的,我用命令强化检查检查了所有无法追踪的二进制文件;这似乎不仅仅与GCC6有关,因为我试图使用GCC5编译,但没有选项(生成了饼图)。此外,我也不确定我的系统二进制文件是如何编译的。在我看来,这与relro
无关,实际上只是now
与lazy
之间的区别。我可以确认@JosephSible说的话,这与现在的vslazy
有关。感谢您关注@JosephSible和SkullTech。我只是习惯于同时使用“now”和“relro”,因为你使用“now”的主要原因是你可以使用“relro”。我不想单独尝试它们,我只是注意到这也可能是其他原因:一些可执行文件似乎最终成为了一个共享库ltrace
在evince
上不工作,而在eog
上工作scanelf
说ENVICE
是ETDYN
而eof
是ETEXEC
。顺便说一句,file
也表示evice
是ELF共享对象,而不是ELF可执行文件。这就是说,evince
也被链接到NOW
@Hibou57 ltrace上,在etdyn
可执行文件上使用lazy
工作正常。