如何在Linux中跟踪系统调用?

lum*_*s12 7 linux kernel system-calls

我将如何跟踪从陷阱到内核的系统调用,如何传递参数,如何在内核中调用系统,如何在内核中实际处理系统调用以及如何返回用户以及状态如何恢复?

Cir*_*四事件 6

系统抽头

这是迄今为止我发现的最强大的方法。它甚至可以显示调用参数:ftrace 是否允许将系统调用参数捕获到 Linux 内核,还是只允许捕获函数名称?

用法:

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

然后在另一个终端上:

sudo rm -rf /tmp/a /tmp/b
mkdir /tmp/a
mkdir /tmp/b
Run Code Online (Sandbox Code Playgroud)

示例输出:

mkdir[4590] -> mkdir("/tmp/a", 0777)
mkdir[4593] -> mkdir("/tmp/b", 0777)
Run Code Online (Sandbox Code Playgroud)

文档: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 最小的可运行示例

/sf/answers/2088833771/中提到,但这里有一个最小的可运行示例。

运行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
Run Code Online (Sandbox Code Playgroud)

示例输出:

# 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)
Run Code Online (Sandbox Code Playgroud)

这种方法的一个很酷的事情是它一次显示系统上所有进程的函数调用,尽管您也可以使用set_ftrace_pid.

文档位于:https : //www.kernel.org/doc/html/v4.18/trace/index.html

在 Ubuntu 18.04、Linux 内核 4.15 上测试。

GDB一步调试Linux内核

根据您需要的内部细节级别,这是一个选项:如何使用 GDB 和 QEMU 调试 Linux 内核?

strace 最小的可运行示例

这是一个最小的可运行示例strace应如何使用 strace?具有独立的 hello world,这使得一切工作的方式非常清楚。

更多信息


Rah*_*thi 2

您可以使用 -f 和 -ff 选项。像这样的东西:

strace -f -e trace=process bash -c 'ls; :'
Run Code Online (Sandbox Code Playgroud)

-f 跟踪当前跟踪的进程由于 fork(2) 系统调用而创建的子进程。

-ff 如果 -o filename 选项有效,每个进程跟踪都会写入 filename.pid,其中 pid 是每个进程的数字进程 ID。这与 -c 不兼容,因为不保留每个进程的计数。


归档时间:

查看次数:

6080 次

最近记录:

6 年,11 月 前