【问题标题】:The trace-cmd report do not show the function nametrace-cmd 报告不显示函数名称
【发布时间】:2022-08-05 17:15:02
【问题描述】:

我使用以下命令来跟踪内核。

$ trace-cmd record -p function_graph ls
$ trace-cmd report

但我看到以下结果只显示地址而不是函数名。

       MtpServer-4877  [000]  1706.014074: funcgraph_exit:       + 23.875 us  |      }
       trace-cmd-4892  [001]  1706.014075: funcgraph_entry:        2.000 us   |      ffff0000082cdc24();
       trace-cmd-4895  [002]  1706.014076: funcgraph_entry:        1.250 us   |        ffff00000829e704();
       MtpServer-4877  [000]  1706.014076: funcgraph_entry:        1.375 us   |      ffff0000083266bc();
         kswapd0-1024  [003]  1706.014078: funcgraph_entry:                   |                ffff00000827956c() {
         kswapd0-1024  [003]  1706.014081: funcgraph_entry:                   |                  ffff00000827801c() {
       trace-cmd-4895  [002]  1706.014081: funcgraph_entry:        1.375 us   |        ffff0000082bd8b4();
       MtpServer-4877  [000]  1706.014082: funcgraph_entry:        1.375 us   |      ffff0000082ccefc();
       trace-cmd-4892  [001]  1706.014082: funcgraph_entry:                   |      ffff0000082c5adc() {
         kswapd0-1024  [003]  1706.014084: funcgraph_entry:        1.500 us   |                    ffff00000828c8f0();
       trace-cmd-4892  [001]  1706.014085: funcgraph_entry:        1.250 us   |        ffff0000082c5a58();
       MtpServer-4877  [000]  1706.014088: funcgraph_entry:        1.125 us   |      ffff0000082e3a30();
       trace-cmd-4895  [002]  1706.014089: funcgraph_exit:       + 19.125 us  |      }
         kswapd0-1024  [003]  1706.014090: funcgraph_entry:        1.500 us   |                    ffff0000090b6c04();
       trace-cmd-4895  [002]  1706.014090: funcgraph_entry:                   |      ffff0000082d4ffc() {
       trace-cmd-4892  [001]  1706.014092: funcgraph_exit:         6.875 us   |      }
       trace-cmd-4895  [002]  1706.014093: funcgraph_entry:        1.000 us   |        ffff0000090b3a40();

我可以知道如何在 trace-cmd 结果上显示确切的函数名称吗?

    标签: linux linux-kernel ftrace


    【解决方案1】:

    我遇到了这个问题,对我来说,这是由 /proc/kallsyms (从内核地址映射到符号名称的文件)显示内核地址全为零引起的。

    由于这是一个 procfs “文件”,因此它的行为可以并且确实会根据您从哪个上下文访问它而有所不同。

    在这种情况下,这是由于安全检查。

    如果您通过了检查,地址将不为零,并且看起来类似于:

    000000000000c000 A exception_stacks
    0000000000014000 A entry_stack_storage
    0000000000015000 A espfix_waddr
    0000000000015008 A espfix_stack
    

    如果您未通过检查,它们将为零,如下所示: (在我的情况下,我没有 CAP_SYSLOG 功能,因为我在容器中运行,而 systemd-nspawn 的默认行为是放弃该功能。[1])

    0000000000000000 A exception_stacks
    0000000000000000 A entry_stack_storage
    0000000000000000 A espfix_waddr
    0000000000000000 A espfix_stack
    

    这受内核设置的影响,更多信息(以及相当简单的检查源代码)可以在Allow single user to access /proc/kallsyms 的答案中找到

    要解决此问题,您需要使用适当的权限/功能启动您的 trace-cmd。

    [1] 这是未经修改的 nspawned 进程的功能设置:

    # cat /proc/2894/status | grep -i cap
    CapInh: 0000000000000000
    CapPrm: 00000000fdecafff
    CapEff: 00000000fdecafff
    CapBnd: 00000000fdecafff
    CapAmb: 0000000000000000
    

    这是在“正常”上下文中由 root 启动的进程的样子:

    # cat /proc/616428/status | grep -i cap
    CapInh: 0000000000000000
    CapPrm: 000001ffffffffff
    CapEff: 000001ffffffffff
    CapBnd: 000001ffffffffff
    CapAmb: 0000000000000000
    

    替代解决方案

    这是我的猜测,但我希望这种对 kallsyms 文件的审查方式是为了防止通过从文件中读取内存位置的地址来破坏 kASLR。

    看来,如果你直接使用tracefs ftrace接口,而不是读取原始跟踪事件然后解析符号(我不知道是否有办法让trace-cmd这样做),那么内核将解析符号为您命名(并且这种方式不会公开内核地址),因此这不是问题。

    例如(注意它是怎么说的!cap_syslog):

    # capsh --print
    Current: =ep cap_syslog-ep
    Bounding set = [...elided for brevity ...]
    Ambient set =
    Current IAB: !cap_syslog
    Securebits: 00/0x0/1'b0 (no-new-privs=0)
     secure-noroot: no (unlocked)
     secure-no-suid-fixup: no (unlocked)
     secure-keep-caps: no (unlocked)
     secure-no-ambient-raise: no (unlocked)
    uid=0(root) euid=0(root)
    gid=0(root)
    groups=0(root)
    Guessed mode: HYBRID (4)
    
    # echo 1 > events/enable 
    # echo function_graph > current_tracer 
    # echo 1 > tracing_on 
    # head trace
     # tracer: function_graph
     #
     # CPU  DURATION                  FUNCTION CALLS
     # |     |   |                     |   |   |   |
      2)   0.276 us    |    } /* fpregs_assert_state_consistent */
      1)   2.052 us    |  } /* exit_to_user_mode_prepare */
      1)               |  syscall_trace_enter.constprop.0() {
      1)               |    __traceiter_sys_enter() {
      1)               |      /* sys_futex(uaddr: 7fc3565b9378, op: 80, val: 0, utime: 0, uaddr2: 0, val3: 0) */
      1)               |      /* sys_enter: NR 202 (7fc3565b9378, 80, 0, 0, 0, 0) */
    

    【讨论】:

      猜你喜欢
      • 2017-12-03
      • 2022-11-25
      • 2022-10-21
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多