strace:如何确定一个系统调用是否调用了另一个系统调用?
“strace 是一个系统调用跟踪器,即一个调试工具,它打印出另一个进程/程序进行的所有系统调用的跟踪。” 如果系统调用递归地工作或者一个系统调用调用另一个系统调用怎么办?我怎样才能得到这些信息?
可能的解决方案 - 我们可以创建一个简单的变量缩进,当我们进入系统调用时增加它,当我们退出时减少它。现在只需在每次调用之前打印“缩进”空格数即可。所以我们可以得到这样的东西 -
05:31:09.449402 getpriority(PRIO_PROCESS, 0) = 20
05:31:09.450514 ioctl(7, 0xc0186201, 0xbef86ac0) = 0
05:31:09.451817 ioctl(7, 0xc0186201, 0xbef86c10) = 0
05:31:09.524328 writev(4, [{"\4", 1}, {"ServiceManager\0", 15}, {"ServiceManager: addService(SMS, 0x15988)\n\0", 42}], 3) = 58
05:31:09.526862 futex(0x134ac, FUTEX_WAKE, 2147483647) = 0
05:31:09.527847 getpriority(PRIO_PROCESS, 0) = 20
05:31:09.528758 ioctl(7, 0xc0186201, 0xbef86ac0) = 0
05:31:09.529847 ioctl(7, 0xc0186201, 0xbef86c10) = 0
strace 或其他一些工具是否已经提供了此功能,或者我是否需要更改源代码来实现此功能?
"strace is a system call tracer, i.e. a debugging tool which prints out a trace of all the system calls made by a another process/program."
What if the systems calls works recursively or one system call calls another system call. How can I get this information?
Possible Solution - We can create a simple variable indent, which we increment when we enter a system call and decrement when we exit. Now just print "indent" number of spaces before each call. So we can get something like this -
05:31:09.449402 getpriority(PRIO_PROCESS, 0) = 20
05:31:09.450514 ioctl(7, 0xc0186201, 0xbef86ac0) = 0
05:31:09.451817 ioctl(7, 0xc0186201, 0xbef86c10) = 0
05:31:09.524328 writev(4, [{"\4", 1}, {"ServiceManager\0", 15}, {"ServiceManager: addService(SMS, 0x15988)\n\0", 42}], 3) = 58
05:31:09.526862 futex(0x134ac, FUTEX_WAKE, 2147483647) = 0
05:31:09.527847 getpriority(PRIO_PROCESS, 0) = 20
05:31:09.528758 ioctl(7, 0xc0186201, 0xbef86ac0) = 0
05:31:09.529847 ioctl(7, 0xc0186201, 0xbef86c10) = 0
Does strace or some other tool already provides this functionality or do I need to change the source code for achieving this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
系统调用被定义为内核空间和用户空间之间的边界,因此任何递归都发生在内核内部并且无法被拦截。
strace
的工作原理是作为调试器附加到进程,让它自由运行,除非触发系统调用,此时会打印参数和返回值。它不知道内核内部发生了什么。System calls are defined as the boundary between kernel and user space, so any recursion there happens inside the kernel and cannot be intercepted.
strace
works by attaching to the process as a debugger, letting it run free except when a system call is triggered, at which point the parameters and return values are printed. It has no knowledge of what goes on inside the kernel.如果您具有 root 访问权限,则可以使用 ftrace 来跟踪内核函数调用,并按内核端系统调用接口的名称进行过滤。
使用 function_graph 作为跟踪器(请参阅 https://lwn.net/Articles/366796/ 了解说明)。
由于“原始系统调用”也通过了这样的调用,因此您将清楚地看到系统调用后调用中的系统调用后调用。
公平警告:我不确定这种情况发生的频率有多高。
If you have root access, you can use ftrace to trace kernel function calls, and filter by the names of the kernel-side syscall interfaces.
Use function_graph as the tracer (see https://lwn.net/Articles/366796/ for an explanation).
Since the "original syscall" also passed through such a call, you would clearly see a post-syscall call within a post-syscall call.
Fair warning: I'm not sure how frequent is this scenario.