Как отследить системный вызов в Linux?

Как я могу следить за системным вызовом из ловушки в ядро, за тем, как передаются аргументы, за тем, как системный вызов находится в ядре, за фактической обработкой системного вызова в ядре, за возвратом обратно пользователю а как состояние восстанавливается?


person luminous12    schedule 24.04.2015    source источник


Ответы (3)


SystemTap

Это самый мощный метод, который я нашел до сих пор. Он даже может отображать аргументы вызова: Разрешает ли ftrace перехват аргументов системного вызова для ядра Linux или только имён функций?

Использование:

sudo apt-get install systemtap
sudo stap -e 'probe syscall.mkdir { printf("%s[%d] -> %s(%s)\n", execname(), pid(), name, argstr) }'

Затем на другом терминале:

sudo rm -rf /tmp/a /tmp/b
mkdir /tmp/a
mkdir /tmp/b

Пример вывода:

mkdir[4590] -> mkdir("/tmp/a", 0777)
mkdir[4593] -> mkdir("/tmp/b", 0777)

Документация: https://sourceware.org/systemtap/documentation.html

Похоже, на основе kprobes: https://sourceware.org/systemtap/archpaper.pdf

См. Также: Как отслеживать только события системных вызовов с помощью ftrace, не показывая никаких других функций в ядре Linux?

Проверено на Ubuntu 18.04, ядро ​​Linux 4.15.

ltrace -S показывает как системные вызовы, так и вызовы библиотеки

Таким образом, этот замечательный инструмент дает еще больше информации о том, что делают исполняемые файлы.

Вот, например, я использовал его, чтобы проанализировать, какие системные вызовы делает dlopen: https://unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

ftrace минимальный запускаемый пример

Упоминается на https://stackoverflow.com/a/29840482/895245, но здесь приводится минимальный работоспособный пример.

Запустите с sudo:

#!/bin/sh
set -eux

d=debug/tracing

mkdir -p debug
if ! mountpoint -q debug; then
  mount -t debugfs nodev debug
fi

# Stop tracing.
echo 0 > "${d}/tracing_on"

# Clear previous traces.
echo > "${d}/trace"

# Find the tracer name.
cat "${d}/available_tracers"

# Disable tracing functions, show only system call events.
echo nop > "${d}/current_tracer"

# Find the event name with.
grep mkdir "${d}/available_events"

# Enable tracing mkdir.
# Both statements below seem to do the exact same thing,
# just with different interfaces.
# https://www.kernel.org/doc/html/v4.18/trace/events.html
echo sys_enter_mkdir > "${d}/set_event"
# echo 1 > "${d}/events/syscalls/sys_enter_mkdir/enable"

# Start tracing.
echo 1 > "${d}/tracing_on"

# Generate two mkdir calls by two different processes.
rm -rf /tmp/a /tmp/b
mkdir /tmp/a
mkdir /tmp/b

# View the trace.
cat "${d}/trace"

# Stop tracing.
echo 0 > "${d}/tracing_on"

umount debug

Пример вывода:

# tracer: nop
#
#                              _-----=> irqs-offhttps://sourceware.org/systemtap/documentation.html
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
           mkdir-5619  [005] .... 10249.262531: sys_mkdir(pathname: 7fff93cbfcb0, mode: 1ff)
           mkdir-5620  [003] .... 10249.264613: sys_mkdir(pathname: 7ffcdc91ecb0, mode: 1ff)

В этом методе замечательно то, что он показывает вызов функции для всех процессов в системе одновременно, хотя вы также можете фильтровать интересующие PID с помощью set_ftrace_pid.

Документация по адресу: https://www.kernel.org/doc/html/v4.18/trace/index.html

Проверено на Ubuntu 18.04, ядро ​​Linux 4.15.

Шаг GDB отладка ядра Linux

В зависимости от необходимого уровня детализации внутренних компонентов это вариант: Как отлаживать ядро ​​Linux с помощью GDB и QEMU?

strace минимальный запускаемый пример

Вот минимальный исполняемый пример strace: Как следует использовать strace? с отдельно стоящим приветственным миром, благодаря которому все работает совершенно ясно.

Дополнительная информация

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 15.08.2018

На самом деле это относительно легко использовать ftrace. Вот классическая статья Стивена, "Mr. ftrace", Rostedt. Вторая часть находится здесь.

Есть бесплатное видео Ян -Simon Möller из Linux Foundation и многие другие хорошие вводные статьи, которые вы можете найти, используя такие условия поиска, как «ftrace tutorial» или «ftrace example».

person Jonathan Ben-Avraham    schedule 24.04.2015

Вы можете использовать опции -f и -ff. Что-то вроде этого:

strace -f -e trace=process bash -c 'ls; :'

-f Отслеживать дочерние процессы по мере их создания текущими отслеживаемыми процессами в результате системного вызова fork (2).

-ff Если действует опция -o filename, трассировка каждого процесса записывается в filename.pid, где pid - это числовой идентификатор каждого процесса. Это несовместимо с -c, поскольку не ведется подсчет для каждого процесса.

person Rahul Tripathi    schedule 24.04.2015
comment
Примечание: процесс относится к понятию ядра процесса, который обычно называется потоком в пользовательском пространстве. - person o11c; 24.04.2015