Вы можете записывать вызовы на системные вызовы, которые были реализованы через vDSO, используя ltrace
вместо strace
. Это связано с тем, что вызовы системных вызовов, реализованные через vDSO, работают иначе, чем «обычные» системные вызовы, а метод strace
использует для отслеживания системных вызовов, не работает с системными вызовами, реализованными в VDSO. Чтобы узнать больше о том, как работает strace
, ознакомьтесь с this blog post I wrote about strace. И, чтобы узнать больше о том, как работает ltrace
, ознакомьтесь с this other blog post I wrote about ltrace.
Нет, невозможно выполнить двоичный код без загрузки linux-vdso.so.1
. По крайней мере, не в моей версии libc на Ubuntu точной. Конечно, возможно, что более новые версии libc/eglibc/etc добавили это как функцию, но это кажется очень маловероятным. См. Следующий ответ, почему.
Если вы удалите адрес из вспомогательного вектора, ваш двоичный файл, скорее всего, сработает. У libc есть piece of code, который сначала попытается пройти объект ELF vDSO, и если это не удастся, он вернется к жестко закодированному адресу vsyscall. Единственный способ избежать этого - собрать компиляцию glibc с отключенным vDSO.
Существует еще одно обходное решение, если вы действительно не хотите использовать vDSO. Вы можете попробовать использовать glibc's syscall
function и передать номер в системном номере gettimeofday
. Это заставит glibc вызвать gettimeofday
через ядро вместо vDSO.
Я включил образец программы, иллюстрирующий это. Вы можете узнать больше о том, как работают системные вызовы, читая мои syscall blog post.
#include <sys/time.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int
main(int argc, char *argv[]) {
struct timeval tv;
syscall(SYS_gettimeofday, &tv);
return 0;
}
Compile с gcc -o test test.c
и Трассирование с strace -ttTf ./test 2>&1 | grep gettimeofday
:
09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>