标签: vdso

什么是vdso和vsyscall?

我做到了 sudo cat /proc/1/maps -vv

我试图弄清楚输出.我可以看到很多共享库按预期映射到内存映射段.

7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
Run Code Online (Sandbox Code Playgroud)

接近尾声有类似的东西

7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0                          [heap]
7fff97863000-7fff97884000 …
Run Code Online (Sandbox Code Playgroud)

c linux kernel linux-kernel vdso

79
推荐指数
2
解决办法
3万
查看次数

system.currentTimeMillis()导致系统CPU使用率过高

我正在我们的风暴监督员(Wheezy机器)上调试高系统CPU使用率(非用户CPU使用率).以下是观察结果

相关过程的输出输出:

Events: 10K cpu-clock
16.40%  java  [kernel.kallsyms]   [k] system_call_after_swapgs
13.95%  java  [kernel.kallsyms]   [k] pvclock_clocksource_read
12.76%  java  [kernel.kallsyms]   [k] do_gettimeofday
12.61%  java  [vdso]              [.] 0x7ffe0fea898f
 9.02%  java  perf-17609.map      [.] 0x7fcabb8b85dc
 7.16%  java  [kernel.kallsyms]   [k] copy_user_enhanced_fast_string
 4.97%  java  [kernel.kallsyms]   [k] native_read_tsc
 2.88%  java  [kernel.kallsyms]   [k] sys_gettimeofday
 2.82%  java  libjvm.so           [.] os::javaTimeMillis()
 2.39%  java  [kernel.kallsyms]   [k] arch_local_irq_restore
Run Code Online (Sandbox Code Playgroud)

在相关过程的线程中捕获了这一点

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000247           0     64038           gettimeofday
  0.00    0.000000           0         1           rt_sigreturn
  0.00 …
Run Code Online (Sandbox Code Playgroud)

java linux kernel vdso

12
推荐指数
1
解决办法
1866
查看次数

调试vsyscall和vdso的信息

我正在使用perf工具来分析centos 6.5上的内核模块(内核版本:2.6.32-431.el6.x86_64).我已经分别安装了内核调试信息包.虽然我能够看到[kernel.kallsyms]函数列表,但是无法识别与[vdso]和[vsyscall]相关的符号并显示为十六进制数字.

有关如何添加这两个库的调试信息的任何想法?

debugging perf vdso

8
推荐指数
0
解决办法
425
查看次数

Linux系统调用,libc,VDSO和实现解析

我在最后一个libc中剖析了syscall调用:

git clone git://sourceware.org/git/glibc.git
Run Code Online (Sandbox Code Playgroud)

我在sysdeps/unix/sysv/linux/i386/sysdep.h中有这个代码:

#   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
LOADREGS_##nr(args)                         \
asm volatile (                          \
"call *%%gs:%P2"                            \
: "=a" (resultvar)                          \
: "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo))        \
  ASMARGS_##nr(args) : "memory", "cc")
Run Code Online (Sandbox Code Playgroud)

如果我理解这段代码,那么LOADREGS _ ## nr(args)宏会将参数加载到寄存器ebx,ecx,edx,esi,edx和ebp中.

sysdeps/UNIX/SYSV/LINUX/I386/sysdep.h中

# define LOADREGS_0()
# define ASMARGS_0()
# define LOADREGS_1(arg1) \
    LOADREGS_0 ()
# define ASMARGS_1(arg1) \
    ASMARGS_0 (), "b" ((unsigned int) (arg1))
# define LOADREGS_2(arg1, arg2) \
    LOADREGS_1 (arg1)
# define ASMARGS_2(arg1, arg2) \
    ASMARGS_1 (arg1), "c" ((unsigned …
Run Code Online (Sandbox Code Playgroud)

c linux libc system-calls vdso

7
推荐指数
1
解决办法
373
查看次数

在strace中捕获vDSO

我在想,如果有一种方法来捕获(即观察)VDSO调用像gettimeofdaystrace.

还有,有没有办法在不加载linux-vdso.so.1(标志或env变量)的情况下执行二进制文件?

最后,如果我编写一个程序linux-vdso.so.1从辅助向量中删除地址然后execve我的程序呢?有人试过吗?

system-calls linux-kernel strace vdso

7
推荐指数
1
解决办法
885
查看次数

是否可以在 glibc 端关闭 vdso?

我知道将 vdso=0 传递给内核可以关闭此功能,并且 glibc 中的动态链接器可以自动检测和使用内核中的 vdso 功能。

在这里我遇到了这个问题。在我的机构中有一个 RHEL 5.6 框(内核 2.6.18-238.el5),我只有普通用户访问权限,可能患有RHEL 错误 673616

当我在其上编译 linux-headers-3.9/gcc-4.7.2/glibc-2.17/binutils-2.23 的工具链时,gcc bootstrap 在 stage2 中的 cc1 中失败无法运行

Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaaaca6eb in ?? ()
(gdb) info sharedlibrary 
From                To                  Syms Read   Shared Object Library
0x00002aaaaaaabba0  0x00002aaaaaac3249  Yes (*)     /home/benda/gnto/lib64/ld-linux-x86-64.so.2
0x00002aaaaacd29b0  0x00002aaaaace2480  Yes (*)     /home/benda/gnto/usr/lib/libmpc.so.3
0x00002aaaaaef2cd0  0x00002aaaaaf36c08  Yes (*)     /home/benda/gnto/usr/lib/libmpfr.so.4
0x00002aaaab14f280  0x00002aaaab19b658  Yes (*)     /home/benda/gnto/usr/lib/libgmp.so.10
0x00002aaaab3b3060  0x00002aaaab3b3b50  Yes (*)     /home/benda/gnto/lib/libdl.so.2
0x00002aaaab5b87b0  0x00002aaaab5c4bb0  Yes (*)     /home/benda/gnto/usr/lib/libz.so.1
0x00002aaaab7d0e70  0x00002aaaab80f62c  Yes (*)     /home/benda/gnto/lib/libm.so.6 …
Run Code Online (Sandbox Code Playgroud)

gcc glibc linux-kernel vdso

5
推荐指数
1
解决办法
1491
查看次数

`[stack]`,`[vdso]`和`[vsyscall]`mmaps来自哪里?

考虑以下针对Linux x86_64的程序:

inf.s:

    .global _start
    .text
_start:
    jmp _start
Run Code Online (Sandbox Code Playgroud)

这基本上是一个无限循环.

如果我链接并删除它,我得到一个ELF可执行文件:

$ gcc -nostdlib inf.s

$ ./a.out &

[1] 15862

$ cat /proc/15862/maps

00400000-00401000 r-xp 00000000 fc:00 11404632           a.out
7fffacdb8000-7fffacdd9000 rwxp 00000000 00:00 0          [stack]
7fffacddd000-7fffacdde000 r-xp 00000000 00:00 0          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0  [vsyscall]
Run Code Online (Sandbox Code Playgroud)

在ELF可执行文件中,第一个程序头LOAD包含占上述mmaps(a.out)中第一个条目的映射.(即使我删除每个,但是这个头和代码都会观察到相同的映射.) execve(2)调用ELF处理程序,fs/binfmt_elf.c其中读取程序头并在文件上调用mmap.

我不明白的是其他三个来自哪里(stack,vdso,vsyscall).它们未在ELF文件中提及,因此Linux内核必须默认设置这三个"匿名"或"特殊"映射.

我的问题是内核代码(或如何)Linux内核创建其他三个映射?他们是否继承了这个人?我似乎无法看到fs/exec.c它们的创建地点.

linux x86 linux-kernel vdso

4
推荐指数
1
解决办法
956
查看次数

gettimeofday() 是否会因为最近宣布的 Intel bug 的修复而变慢?

我一直在使用netmap估计最近宣布的英特尔错误对我的数据包处理应用程序的影响。到目前为止,我测量到每个poll()系统调用处理大约 50 个数据包,但这个数字不包括gettimeofday()调用。我还测量到每秒可以从不存在的文件描述符中读取 1650 万次(这大约是系统调用可以执行的最便宜的操作)。我的数据包处理速率是每秒176万个数据包,或者就系统调用而言,每秒0.352万个系统调用。这意味着如果系统调用惩罚加倍,性能将降低 0.0352 / 16.5 = 0.21333%,这几乎是我不应该担心的事情。

但是,我的应用程序可能gettimeofday()经常使用系统调用。我的理解是,这些不是真正的系统调用,而是作为虚拟系统调用实现的,如什么是 vdso 和 vsyscall?

现在,我的问题是,对最近宣布的 Intel bug 的修复(也可能影响 ARM,但可能不会影响 AMD)是否会减慢gettimeofday()系统调用速度?或者是gettimeofday()由于作为不同类型的虚拟系统调用而实现的完全不同的动物?

intel linux-kernel vdso

4
推荐指数
1
解决办法
649
查看次数

gettimeofday() 不使用 vDSO?

我跟踪了一个 java 进程,该进程触发了大量内核时间来查看正在使用的系统调用,并且惊讶地看到它gettimeofday()clock_gettime()占主导地位(我怀疑这是由于日志记录),考虑到以下man vdso状态,这很奇怪:

使用strace (1)跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。

这些系统调用是怎么发生的?有没有办法避免它们?

该机器在 EC2 上运行 Ubuntu 16.04.1。

为方便起见,我用 C ( testgtod.c)创建了一个最小的测试程序:

#include <stdlib.h>
#include <sys/time.h>

void main(void)
{
    struct timeval tv;
    for(int i = 0; i < 1000; i++) {
        /* glibc wrapped, shouldn't actually syscall */
        gettimeofday(&tv, NULL);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在strace下编译并运行程序: gcc testgtod.c -o testgtod && sudo strace ./testgtod

输出包括对 gettimeofday() 的一千次调用,尽管我有预料。

我测试过的东西以确保我看不到东西:

  1. 确保二进制文件是一个 64 位精灵使用 file

  2. ldd ./testgtod 确保 vDSO 处于活动状态:

    linux-vdso.so.1 => (0x00007ffcee25d000) …

amazon-ec2 linux-kernel vdso

3
推荐指数
1
解决办法
2698
查看次数

即使使用 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 库,则可以解释。但是,VDSO 用于每个clock_gettime(我通过strace 检查过)。

无论相应的线程是否关联到某个 CPU 内核。不管这个CPU内核是否与操作系统隔离。这意味着测试应用程序可能会在独占 CPU 内核上运行,而无论如何可能会出现延迟!

我通过比较两个随后的 clock_gettime 调用的结果来测量延迟,例如:

unsigned long long __gettimeLatencyNs() {
    struct timespec t1_ts;
    struct timespec t2_ts;
    clock_gettime(CLOCK_MONOTONIC, &t1_ts);
    clock_gettime(CLOCK_MONOTONIC, &t2_ts);
    return ((t2_ts.tv_sec - t1_ts.tv_sec)*NANO_SECONDS_IN_SEC + t2_ts.tv_nsec - t1_ts.tv_nsec);
}  
Run Code Online (Sandbox Code Playgroud)

任何人都可以分享一些想法,那里可能有什么问题?

linux time-measurement vdso

3
推荐指数
2
解决办法
2674
查看次数

标签 统计

vdso ×10

linux-kernel ×6

linux ×5

c ×2

kernel ×2

system-calls ×2

amazon-ec2 ×1

debugging ×1

gcc ×1

glibc ×1

intel ×1

java ×1

libc ×1

perf ×1

strace ×1

time-measurement ×1

x86 ×1