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

查看:12
本文介绍了如何使用 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 并禁用系统调用事件,但是如果我可以使用更具体的事件感觉更干净?还有:

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:

  • 事件显示参数,这更好.
  • 系统调用函数名称会随着内核版本而变化.例如,在 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.

推荐答案

使用nop tracer

Use the nop tracer

作为 由sruffell 提出,我们所要做的就是使用nop 跟踪器而不是function,这将禁用函数跟踪,但是不是事件.

As proposed by sruffell, all we have to do is to use the nop tracer instead of function, and that will disable the function traces, but not the events.

使用 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

这给出了所需的输出:

   mkdir-26064 [007] .... 2014370.909743: sys_mkdir(pathname: 7fffbd461c77, mode: 1ff)
   mkdir-26065 [014] .... 2014370.911615: sys_mkdir(pathname: 7ffea53bac77, mode: 1ff)

替代不是最佳的解决方案

这也有效,但肯定不太好,替换:

This also works, but definitely less nice, replace:

echo SyS_mkdir > "${d}/set_ftrace_filter"

与:

echo '*' > "${d}/set_ftrace_notrace"

这会关闭文档中提到的所有功能:https://www.kernel.org/doc/html/v4.18/trace/ftrace.html#the-file-system

This turns off all functions as mentioned in the docs: https://www.kernel.org/doc/html/v4.18/trace/ftrace.html#the-file-system

set_ftrace_notrace:

set_ftrace_notrace:

这与 set_ftrace_filter 的效果相反.在此添加的任何功能都不会被追踪.如果 set_ftrace_filter 和 set_ftrace_notrace 中都存在一个函数,则该函数将被跟踪.

This has an effect opposite to that of set_ftrace_filter. Any function that is added here will not be traced. If a function exists in both set_ftrace_filter and set_ftrace_notrace, the function will not be traced.

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

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