在Linux上跟踪libc和系统调用函数的调用?

4

我在Linux上有一个C++应用程序。如何在程序执行期间查看库调用,例如malloc(),然后跟踪到系统调用,例如sbrk()等等?

我希望能够显示出哪些libc函数发生了并导致了后续的Linux系统调用。

NB:我不希望拦截任何函数调用,只是记录哪些C库函数调用了哪些系统调用。

3个回答

8
我希望能够展示哪些libc函数发生并负责后续的Linux系统调用。
你可能需要使用ltrace(1)和/或strace(1)
当然,可以阅读syscalls(2)Advanced Linux Programming,或使用ld.so(8)技巧与动态链接器。你也可以阅读Linkers and Loaders
我相信编译应用程序时启用所有警告和调试信息(例如g++ -Wall -Wextra -g)应该有所帮助(特别是提供更好的输出)。您甚至可能想要安装某些系统库的调试变体(在Debian或Ubuntu上,例如libstdc++6-4.8-dbg等软件包)。
只有当您认为已经纠正了大多数错误后,才启用优化重新编译代码
(实际上意味着:将-O2添加到g++程序选项中,因此请适当配置您的构建自动化工具,例如如果您使用GNU make,请编辑您的Makefile)。

如果您在2020年使用最新的GCC 10,请考虑使用其静态分析器选项。还可以考虑使用Frama-CClang静态分析器

你还应该考虑使用valgrind,并且对于最近的GCC编译器,使用一些消毒选项(例如-fsanitize=address),当然还要启用所有警告和DWARF调试信息(因此也要将-Wall -Wextra -g传递给gccg++)。
而且,你可以使用最新的GDB调试器半自动跟踪一些函数,因为gdb may be scriptable在Python或Guile中。
另一种方法(参见this draft报告)是编写自己的GCC插件,然后在编译您自己或其他源代码时使用它。

顺便说一下,要想了解标准库的工作方式(即调用哪些系统调用),你不仅可以使用strace跟踪使用它们的程序,还可以因为Linux上许多库都是自由软件开源的,所以下载并学习它们的源代码。我发现musl-libc的源代码非常易读。另外还有更常见的Gnu libc。C++标准库打包在GCC内部。

如果想要系统化的方法,请阅读LinuxFromScratch。如果有足够的耐心(需要数周时间),你可以编译所有的Linux软件(或使用基于源代码的发行版,例如Gentoo)。


1
这个答案很有启发性!它值得更多的赞。 - chqrlie

6

您可以从以下开始:

man ld-linux
export LD_DEBUG=help

例如,我想了解ls命令使用了哪些功能:

export LD_DEBUG=symbols
export LD_DEBUG_OUTPUT=myoutput.txt
[xxxx@localhost ~]$ ls -l
total 244
-rw-rw-r--   1 xxxxx pppppp    247 Jul 15 12:05 28_29storage.txt

现在在myoutput.txt.pidnumber文件中,我有以下内容:

   13419:   symbol=malloc;  lookup in file=ls [0]
   13419:   symbol=malloc;  lookup in file=/lib64/libselinux.so.1 [0]
   13419:   symbol=malloc;  lookup in file=/lib64/libcap.so.2 [0]
   13419:   symbol=malloc;  lookup in file=/lib64/libacl.so.1 [0]
   13419:   symbol=malloc;  lookup in file=/lib64/libc.so.6 [0]

1
你可以像前面的回答所提到的那样使用ltrace/strace进行系统调用。为了追踪libc调用,你需要决定要追踪哪些特定的调用,并创建一个使用LD_PRELOAD覆盖它们的库。
请参见在C中创建malloc和free的包装函数,了解如何执行此操作的详细信息。

你比我先一步,我想看看new() -> malloc()在sbrk()/mmap()等方面的具体操作。 - user997112

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接