如何使用ftrace跟踪系统调用事件,而又不显示Linux内核中的任何其他函数? [英] How to trace just system call events with ftrace without showing any other functions in the Linux kernel?

查看:420
本文介绍了如何使用ftrace跟踪系统调用事件,而又不显示Linux内核中的任何其他函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,要监视所有mkdir呼叫,我能想到的最好的方法是:

For example, to monitor all mkdir calls made, the best I could come up with was:

#!/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"

# Enable tracing mkdir
echo sys_enter_mkdir > "${d}/set_event"

# Set tracer type.
echo function > "${d}/current_tracer"

# Filter only sys_mkdir as a workaround.
echo SyS_mkdir > "${d}/set_ftrace_filter"

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

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

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

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

umount debug

然后使用sudo运行后,它会给出:

And then after running with sudo it gives:

# tracer: function
#
# entries-in-buffer/entries-written: 4/4   #P:16
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
           mkdir-31254 [015] .... 2010985.576760: sys_mkdir(pathname: 7ffc54b32c77, mode: 1ff)
           mkdir-31254 [015] .... 2010985.576763: SyS_mkdir <-tracesys_phase2
           mkdir-31255 [007] .... 2010985.578363: sys_mkdir(pathname: 7fff02d90c77, mode: 1ff)
           mkdir-31255 [007] .... 2010985.578365: SyS_mkdir <-tracesys_phase2

我的问题是,它为每个系统调用输出两行:

My problem with this is that it output two lines for each syscall:

  • sys_mkdir这是我想要的事件
  • SyS_mkdir这是过滤后的功能解决方法,我不想看到
  • sys_mkdir which is the event that I want
  • SyS_mkdir which is the filtered function workaround, which I don't want to see

如果我改为尝试做:

echo > "${d}/set_ftrace_filter"

或者根本不触摸该文件,那么它显示了大量的功能,使查找系统调用变得非常困难.

or don't touch that file at at all, then it shows a ton of functions and makes it hard to fint the syscall at all.

是否有更好的方法来禁用常规功能,并仅保留系统调用事件?

If there a nicer way to disable regular functions, and keep just syscall events?

我可以只使用SyS_mkdir并禁用我猜想的syscall事件,但是如果我可以使用更具体的事件,那感觉就更干净了?另外:

I could use just SyS_mkdir and disable the syscall event I guess, but it feels cleaner if I could use the more specific event? Also:

  • 该事件显示参数,这更好.
  • syscall函数名称在内核版本之间会发生变化.例如,在Linux v4.18上,它已经是__x64_sys_mkdir而不是SyS_mkdir.
  • the event shows arguments, which is nicer.
  • syscall function names change across kernel versions. E.g., it is already __x64_sys_mkdir instead of SyS_mkdir on Linux v4.18.

相关:

在Ubuntu 18.04,Linux内核4.15上进行了测试.

Tested on Ubuntu 18.04, Linux kernel 4.15.

推荐答案

此外,值得一提的另一种简洁的方式来获取此类信息.一个人可以做类似的事情:

In addition, it's worth mention another concise way to gain such info. One can do something like:

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

输出:

systemd-journal[318] -> mkdir("/var/log/journal/c8d2562a041649cdbfd1ac5e24dbe0db", 0755)
systemd-journal[318] -> mkdir("/var/log/journal/c8d2562a041649cdbfd1ac5e24dbe0db", 0755)
mkdir[4870] -> mkdir("wtf", 0777)
...

另一种方式:

stap -e 'probe kernel.function("sys_mkdir") { printf("%s[%d] (%s)\n", execname(), pid(), $$parms) }'

输出:

systemd-journal[318] (pathname=0x55b74f7ab8b0 mode=0x1ed)
systemd-journal[318] (pathname=0x55b74f7ab8b0 mode=0x1ed)
mkdir[8532] (pathname=0x7ffcf30af761 mode=0x1ff)
...

您可以根据需要自定义输出.

You can customize the output as you like.

P.S. Systemtap基于 kprobes . 架构文档将有助于了解其内部.

P.S. Systemtap is based on kprobes. Architecture doc will help to understand its internals.

有关 SystemTap的更多信息 .

这篇关于如何使用ftrace跟踪系统调用事件,而又不显示Linux内核中的任何其他函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆