linux - 如何根据网络接口(interface)名称获取 trace-cmd 报告(例如 : eth2)?

标签 linux debugging linux-kernel kernel ftrace

有什么方法可以根据网络接口(interface)名称(例如:eth1 或 eth2)过滤掉 trace-cmd 报告?
当我尝试在 trace-cmd 报告过滤器中使用“名称”作为 EVENT_FIELD 时,我什么也没得到。
以下是我使用的命令

  [prap4test]$trace-cmd report -F 'net/netif_receive_skb:name=="eth1"'
  version = 6
  cpus=2
  [prap4test]$

但我能够使用“len”作为 EVENT_FIELD

[prap4test]$trace-cmd report -F 'net/netif_receive_skb'
version = 6
cpus=2
       trace-cmd-19979 [000] 499726.602505: netif_receive_skb:    dev=eth2 skbaddr=0xffff8800e9bb0e00 len=84
            sshd-21184 [000] 499726.603209: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e9bb0f00 len=52
       trace-cmd-19978 [000] 499727.809932: netif_receive_skb:    dev=eth2 skbaddr=0xffff8800e9bb5000 len=46
       trace-cmd-19979 [001] 499728.105372: netif_receive_skb:    dev=eth2 skbaddr=0xffff8800e753cc00 len=328
       trace-cmd-19978 [000] 499728.780571: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e9bb0700 len=100
[prap4test]$trace-cmd report -F 'net/netif_receive_skb:len >= 50'
version = 6
cpus=2
       trace-cmd-19979 [000] 499726.602505: netif_receive_skb:    dev=eth2 skbaddr=0xffff8800e9bb0e00 len=84
            sshd-21184 [000] 499726.603209: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e9bb0f00 len=52
       trace-cmd-19979 [001] 499728.105372: netif_receive_skb:    dev=eth2 skbaddr=0xffff8800e753cc00 len=328
       trace-cmd-19978 [000] 499728.780571: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e9bb0700 len=100

netif_receive_skb的事件格式如下

name: netif_receive_skb
ID: 991
format:
        field:unsigned short common_type;       offset:0;       size:2; signed:0;
        field:unsigned char common_flags;       offset:2;       size:1; signed:0;
        field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
        field:int common_pid;   offset:4;       size:4; signed:1;

        field:void * skbaddr;   offset:8;       size:8; signed:0;
        field:unsigned int len; offset:16;      size:4; signed:0;
        field:__data_loc char[] name;   offset:20;      size:4; signed:1;

print fmt: "dev=%s skbaddr=%p len=%u", __get_str(name), REC->skbaddr, REC->len

在 trace-cmd-report 中我发现了以下细节

Note, the EVENT_FIELD is the field name as shown by an events format
(as displayed with *--events*), and not what is found in the output.
If the output shows "ID:foo" but the field that "foo" belongs to was
called "name" in the event format, then "name" must be used in the filter.
The same is true about values. If the value that is displayed is converted
by to a string symbol, the filter checks the original value and not the
value displayed. For example, to filter on all tasks that were in the
running state at a context switch:

    -F 'sched/sched_switch : prev_state==0'

Although the output displays 'R', having 'prev_stat=="R"' will not work.

简而言之,我想知道根据“名称”EVENT_FIELD 过滤掉的命令

提前致谢,
prap4search

最佳答案

这确实是 trace-cmd 中的一个错误。
我从 Steven Rostedt(trace-cmd 的创建者)那里获得了以下补丁作为修复。

diff --git a/parse-filter.c b/parse-filter.c
index c2fd26f..8e302c4 100644
--- a/parse-filter.c
+++ b/parse-filter.c
@@ -1880,17 +1880,25 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
    struct pevent *pevent;
    unsigned long long addr;
    const char *val = NULL;
+    unsigned int size;
    char hex[64];

    /* If the field is not a string convert it */
    if (arg->str.field->flags & FIELD_IS_STRING) {
        val = record->data + arg->str.field->offset;
+        size = arg->str.field->size;
+
+        if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
+            addr = *(unsigned int *)val;
+            val = record->data + (addr & 0xffff);
+            size = addr >> 16;
+        }

        /*
        * We need to copy the data since we can't be sure the field
        * is null terminated.
        */
-        if (*(val + arg->str.field->size - 1)) {
+        if (*(val + size - 1)) {
            /* copy it */
            memcpy(arg->str.buffer, val, arg->str.field->size);
            /* the buffer is already NULL terminated */

应用补丁后,我可以使用接口(interface)名称过滤掉

[prap4test]$../trace-cmd/trace-cmd report -F 'net/netif_receive_skb:name=="eth1"'
cpus=2
       trace-cmd-1108  [000] 1111798.397704: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e9f5ee00 len=52
       trace-cmd-1108  [000] 1111798.428998: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e867b400 len=392
       trace-cmd-1108  [000] 1111798.989447: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e743ed00 len=46
       trace-cmd-1108  [000] 1111799.450838: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800eab94b00 len=576
       trace-cmd-1108  [000] 1111799.549737: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800eab94700 len=576
       trace-cmd-1108  [000] 1111800.263439: netif_receive_skb:    dev=eth1 skbaddr=0xffff8800e87c4e00 len=100

关于linux - 如何根据网络接口(interface)名称获取 trace-cmd 报告(例如 : eth2)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44835431/

相关文章:

c++ - 忽略 g++ 编译错误以获得向后兼容性的额外资格

linux - 使用 awk 将 csv 拆分为多个带标题的文件

linux - 我的 Android 手机中有大约 50 个 kcryptd 进程?

javascript - 使用 Vorlon 调试 iPad Safari

c - SK_BUFF 结构成员

c - 测试内核模块

linux - 安装 Mininet 时出错

json - 从调试器获取 IntelliJ Idea 中的 JSON 对象

linux - 在 Linux 上调试内存泄漏

timer - 为什么linux内核中的udelay和ndelay不准确?