我有一个现代 Linux 桌面,其中有许多同时运行的进程。其中一个进程,我不知道是哪一个,some_func
从流行的动态库中调用一个函数some_lib
(想想libc
or libx11
,所以很多进程都使用它),我想知道是什么进程这样做(理想情况下,有一个每次调用的堆栈跟踪)。
如何确定调用哪个进程some_lib
?
到目前为止我考虑过的选项:
- 使用
ltrace
orlatrace
:拥有一个ltrace
- 样式的详细列表,其中列出了我感兴趣的函数的调用,哪些参数是完美的,但ltrace
仅适用于单个进程或进程组。我不能只输入ltrace -e some_func@some_lib -fp 1
并查看系统范围内的所有用途。 - 查找哪些进程使用我的库
lsof
,然后继续执行步骤 1:这将非常麻烦,因为有太多进程使用同一个库,但没有调用所述函数。 grep -r some_func /usr
,然后看看是否只有几个二进制文件能够调用该函数,然后从那里开始工作。尽管这可以在一些有限的情况下工作,但这绝不是一个通用的解决方案,如果 egsome_func
在各种二进制文件中无处不在但很少被调用,则不会工作。- 使用内核审计系统。如果我正在跟踪一个系统调用,我可以键入
auditctl -S some_syscall ...
,这样就可以记录系统范围的调用。但是,auditctl
似乎无法使用库函数执行相同级别的粒度。 - 最后,我可以重建库,在我感兴趣的函数中添加一个新行,以记录它的所有调用。虽然这可以保证解决我的问题,但该解决方案会很麻烦,并且需要修改/重新编译库并至少重新启动 2 次以推出检测库并在找到罪魁祸首后将其回滚。
有没有更简单的方法?
(我想指出,这是一个一般性问题,并且我最感兴趣的是可以正常工作的一般性解决方案。)
我找到了一篇不错的比较文章,其中提到了一些我不知道的追踪设施,这可能值得探索。
带有 debuginfo 的 SystemTap 可以跟踪库中的函数调用;在 Centos 7 系统上:
这可以用作
probe
打印回溯的点或可以使用 SystemTap 编写的任何内容:保存,因为
probelibraryfunc.stp
这可以通过虽然如果调用很常见,可能会产生大量的输出......