问题标签 [vdso]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - 使实现为 vDSO 的函数实际上是系统调用?
有没有办法导致这种情况发生(没有重新编码调用的每个实例,比如time()
调用syscall()
?
linux-kernel - 在 strace 中捕获 vDSO
我想知道是否有一种方法可以捕获(换句话说,观察)vDSO 调用,例如gettimeofday
in strace
。
另外,有没有办法在不加载linux-vdso.so.1
(标志或环境变量)的情况下执行二进制文件?
最后,如果我编写一个程序linux-vdso.so.1
从辅助向量中删除地址然后execve
我的程序呢?有人试过吗?
c - vdso gettimeofday 与 64 位内核和为 32 位编译的应用程序
运行在 64 位内核和 glibc 2.15 版的 32 位应用程序是否支持 vdso?如果是,我如何使它适用于在 64 位内核上运行的 32 位应用程序。?因为即使“linux-vdso.so.1”上的 dlopen 成功,“__vdso_gettimeofday”上的 dlsym 也会失败。
在同一系统上,我可以从为 64 位编译的应用程序中对“linux-vdso.so.1”和“__vdso_gettimeofday”上的 dlsym 执行 dlopen。
amazon-ec2 - gettimeofday() 不使用 vDSO?
我 strace'd 一个触发大量内核时间的 java 进程以查看正在使用的系统调用,并且惊讶地看到它gettimeofday()
并clock_gettime()
占主导地位(我怀疑这是由于日志记录),考虑到这些man vdso
状态,这很奇怪:
使用strace (1) 跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。
这些系统调用是怎么发生的?有没有办法避免它们?
该机器在 EC2 上运行 Ubuntu 16.04.1。
为了让事情变得更简单,我用 C ( testgtod.c
) 创建了一个最小的测试程序:
然后我在 strace 下编译并运行程序:gcc testgtod.c -o testgtod && sudo strace ./testgtod
尽管我的预期是,输出包括对 gettimeofday() 的一千次调用。
我测试的东西以确保我没有看到东西:
确保二进制文件是 64 位精灵使用
file
ldd ./testgtod
确保 vDSO 处于活动状态:linux-vdso.so.1 => (0x00007ffcee25d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f6e161000) /lib64/ld-linux-x86-64.so.2 (0x0000559ed71f3000)
getauxval(AT_SYSINFO_EHDR) != NULL
gettimeofday(&tv, NULL)
将调用替换为syscall(SYS_gettimeofday, &tv, NULL)
,调用次数增加到 1000 万次,time
在两种情况下运行时的行为都是相同的:./testgtod 0.16s user 0.83s system 99% cpu 0.998 total
.
c - 如何检查 vsdo 变量?
我想检查 vsyscall_gtod_data 的内容(所有时间保持使clock_gettime()工作所需的相关信息)。
我正在使用 gdb 单步执行 __vdso_clock_gettime() 的汇编代码,并且正在查看以下部分:
我相信是以下 C 代码的程序集(来自 linux-4.8.0/arch/x86/include/asm/vgtod.h):
(汇编指令pause
匹配cpu_relax()
)
据我了解,它struct vsyscall_gtod_data *s
被保存rbx
并在本指令中读取地址:
这意味着被调试的程序可以读取这个地址,但是当我尝试在 gdb 中检查它时,我得到一个错误:
关于发生了什么以及如何检查该记忆的任何想法?
linux - glibc中的getpid工作流程是什么?
情况如下:
我正在尝试做一个在 github 中破解内核的项目。内核版本为 linux-3.18.6。
QEMU 用于模拟环境。
在我的应用程序中,我尝试通过跟随它们来理解系统调用过程。完成我的目标的方法就像shell程序一样。我只是创建一些命令来运行相对系统调用。也许通过图片很简单。 一些命令
代码很简单如下:
1 使用 API getpid。
2 直接使用 int $0x80。
因为我的应用程序只是在 pid 1 的进程中运行,所以每次我输入命令 getpid 时,它都会返回 1。当然这是真的。
奇怪的是,当我使用 gdb 调试 syscall 进程时,它只会在我键入 getpid 执行时在 berakpoint sys_getpid 处停止一次。当我一次又一次地这样做时,它只是不停地输出。
显然,据我所知,使用 int $0x80 是绝对正确的。
为了解决这个问题,我做了一些研究。我下载了 glibc 源代码(glibc-2.25)代码来查看 api getpid 如何包装 int $0x80。不幸的是,它不在那里,或者我只是没有找到正确的位置。
glibc 中的一些代码。
如果我得到了错误的代码,请告诉我,tks。
如代码所示,glibc 中不包含 getpid 的定义。看了一些资料后,有人说VDSO ....
请注意,AFAIK,简单系统调用成本的很大一部分是从用户空间到内核并返回。因此,对于某些系统调用(可能是 gettimeofday、getpid ...),VDSO 甚至可以避免这种情况(并且在技术上可能会避免进行真正的系统调用)。
在 man getpid pgae 中:
C 库/内核差异 从 glibc 2.3.4 版本开始,glibc 的 getpid() 包装函数会缓存 PID,以避免在进程重复调用 getpid() 时产生额外的系统调用。通常这种缓存是不可见的,但它的正确操作依赖于对 fork(2)、vfork(2) 和 clone(2) 的包装器函数的支持:如果应用程序通过使用 syscall(2) 绕过这些系统调用的 glibc 包装器),然后在子进程中调用 getpid() 将返回错误的值(准确地说:它将返回父进程的 PID)。另请参阅 clone(2) 以讨论 getpid() 可能返回错误值的情况,即使通过 glibc 包装函数调用 clone(2) 也是如此。
虽然有这么多的解释,但我无法弄清楚API getpid的工作过程。
相比之下,API 时间很容易理解。时间的定义:
然后,
最后,它是嵌入式 asm,这是使用内核源代码的正常方式。
有人可以清楚地解释 API getpid 是如何工作的吗?为什么 getpid 只陷入系统调用 sys_getpid 一次?如果可能的话,一些参考是值得赞赏的。
谢谢你的帮助。
linux - 即使使用 VDSO,clock_gettime 也可能非常慢
我在 Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz 上使用 CentOS Linux 版本 7.3.1611
在我的用户空间应用程序测试期间,我注意到 clock_gettime(CLOCK_MONOTONIC, &ts) 可能需要 5-6 微秒而不是平均约 23 纳秒。它可能每 10000 个后续调用仅发生一次,但是它可能会发生。
如果没有 VDSO 库,可以解释。但是,每个clock_gettime都使用VDSO(我通过strace检查了它)。
无论对应的线程是否与某个 CPU 核心关联。不管这个 CPU 内核是否与操作系统隔离。这意味着测试应用程序可能会在独占 CPU 内核上运行,而无论如何可能会出现延迟!
我通过比较两个随后的 clock_gettime 调用的结果来测量延迟,例如:
任何人都可以分享一些想法,那里可能有什么问题?
java - High System CPU usage because of system.currentTimeMillis()
I was debugging high System CPU usage (Not user CPU usage) on of our storm supervisors (Wheezy machine). Here are the observations
Output of perf for the relevant process:
Caught this in strace of a thread of the relevant process
Finally figured out that the thread was running in while(true)
and one of the calls inside was System.currentTimeMillis()
. I disabled the same and the system CPU % went down from 50% to 3%. So clearly that was the issue. What I fail to understand is, in the presence of vDSO these kernel calls should only happen in the user's address space. But as is clear from perf report, kernel calls are indeed taking place in the kernel space. Any pointers on this?
Kernel version: 3.2.0-4-amd64 Debian 3.2.86-1 x86_64 GNU/Linux
clock type: kvm
Adding code of the problematic thread.
linux-kernel - gettimeofday() 是否会因修复最近公布的 Intel 错误而变慢?
我一直在估计最近公布的英特尔错误对我使用netmap的数据包处理应用程序的影响。到目前为止,我测量到每个poll()
系统调用处理大约 50 个数据包,但这个数字不包括gettimeofday()
调用。我还测量到每秒可以读取 1650 万次不存在的文件描述符(这是系统调用可以做的最便宜的事情)。我的数据包处理速率是每秒 176 万个数据包,或者就系统调用而言,每秒 03.52 万个系统调用。这意味着如果系统调用惩罚加倍,性能下降将是 0.0352 / 16.5 = 0.21333%,这几乎不是我应该担心的。
但是,我的应用程序可能会gettimeofday()
经常使用系统调用。我的理解是,这些不是真正的系统调用,而是作为虚拟系统调用实现的,如什么是 vdso 和 vsyscall?.
现在,我的问题是,对最近宣布的 Intel 错误(也可能会影响 ARM,可能不会影响 AMD)的修复是否会减慢gettimeofday()
系统调用速度?还是gettimeofday()
因为被实现为不同类型的虚拟系统调用而导致完全不同的动物?