linux - 为什么 strace 会根据环境/内核(随机)忽略某些系统调用?

标签 linux linux-kernel system-calls strace vdso

如果我编译以下程序:

$ cat main.cpp && g++ main.cpp
#include <time.h>
int main() {
    struct timespec ts;
    return clock_gettime(CLOCK_MONOTONIC, &ts);
}

然后在“标准”Kubuntu 中的 strace 下运行它,我明白了:

strace -tt --trace=clock_gettime ./a.out
17:58:40.395200 +++ exited with 0 +++

如您所见,没有 clock_gettime(完整的 strace 输出为 here )。

另一方面,如果我在 qemu 下自定义构建的 linux 内核中运行相同的应用程序,我会得到以下输出:

strace -tt --trace=clock_gettime ./a.out
18:00:53.082115 clock_gettime(CLOCK_MONOTONIC, {tv_sec=101481, tv_nsec=107976517}) = 0
18:00:53.082331 +++ exited with 0 +++

哪个更值得期待 - clock_gettime

所以,我的问题是:

  • 如果我在 Kubuntu 中运行 strace 为什么会忽略/省略 clock_gettime
  • 为什么 strace 的行为因环境/内核而异?

最佳答案

第一个问题的答案

来自 vdso man

strace(1)、seccomp(2) 和 vDSO

当使用 strace(1) 跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。这些系统调用同样对 seccomp(2) 过滤器不可见。

Answer对于第二个问题:

在vDSO中,clock_gettimeofday和相关函数依赖于特定的时钟模式;参见 __arch_get_hw_counter。

如果时钟模式是 VCLOCK_TSC,则在没有系统调用的情况下读取时间,使用 RDTSC;如果它是 VCLOCK_PVCLOCK 或 VCLOCK_HVCLOCK,则从特定页面读取它以从管理程序检索信息。 HPET 没有声明时钟模式,因此它以默认的 VCLOCK_NONE 结束,vDSO 发出系统调用以检索时间

确实:

在默认内核中(来自 Kubuntu):

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc

定制内核:

$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
hpet

More info关于各种时钟源。特别是:

The documentation of Red Hat MRG version 2 states that TSC is the preferred clock source due to its much lower overhead, but it uses HPET as a fallback. A benchmark in that environment for 10 million event counts found that TSC took about 0.6 seconds, HPET took slightly over 12 seconds, and ACPI Power Management Timer took around 24 seconds.

关于linux - 为什么 strace 会根据环境/内核(随机)忽略某些系统调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68535146/

相关文章:

linux - 我想在发生错误时读取另一个内核

linux - 如何在没有提示的情况下执行 ssh-keygen

javascript - 通过网络将系统音频流式传输到 Web 浏览器 (javascript)

c - 程序不在声明的目录路径中运行,仅在当前目录中运行

c - 使用 lseek 时不打印第一个字节

linux - 每小时从每日日志文件中捕获日志

io - 如何判断给定进程是否使用 O_DIRECT 打开文件?

operating-system - 什么是梯形调节器和菜单调节器?

c - 什么会导致 printk 不会立即显示在 dmesg 中?

c++ - char* 和 char[] 没有得到相同的输出