只是要求确认 strace 输出是系统调用的名称,而不是执行这些实际系统调用的包装函数的名称
一般是的;
strace
的工作原理是使用 ptrace(2)
来专门跟踪系统调用,使用 PTRACE_SYSCALL
要求内核在下一个系统调用处停止。
所以
strace
只发现tracee实际进入内核时发生了什么,并根据寄存器值进行解码。 (在具有最新内核和 strace 的 x86-64 上,用户空间是否使用 64 位 syscall
ABI 还是 32 位 int 0x80
ABI,它们具有不同的调用号和参数传递寄存器,但 32 位 ABI 可用于 64 位代码。)
与
ltrace
不同,它不读取用户空间库符号表。
但是
strace
可能对 32 位 x86 socketcall
系统调用有特殊解码,这是一个包装 socket(2)
、bind(2)
、listen(2)
等的内核函数。(请参阅 相关 Q&A 上的答案)。
在这种情况下,它可能仍然会打印
listen(...)
而不是用户空间实际进行的 socketcall(SYS_LISTEN, ...)
原始系统调用。不过我没查过。
但是我的系统(Linux 内核 6.7)上的
asm/unistd_32.h
现在有 __NR_listen
等条目,因此现代 32 位 glibc 版本现在可能会使用这些而不是 socketcall
。在这种情况下,glibc 包装器名称确实对应于实际的系统调用。这些调用号码低于 Linux 内核版本 4.3 中添加的 __NR_membarrier
,所以大概在那之前不久。