You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Linux内核跟踪点转换为printk?编译时启用方案问询

编译时启用跟踪点并输出至内核日志的解决方案

方法1:通过内核编译配置强制启用跟踪点

  • 开启内核编译配置CONFIG_TRACEPOINTS=y,同时确保CONFIG_PRINTK=y(多数内核默认已开启)。
  • 针对特定子系统的跟踪点,可直接开启对应配置项,比如网络子系统的CONFIG_NET_TRACEPOINTS=y,编译时这些跟踪点会被直接编译进内核。

方法2:修改跟踪点定义,编译时绑定日志输出

  • 找到目标跟踪点的定义文件(通常位于include/trace/events/或对应子系统目录),例如调度子系统的trace/events/sched.h。
  • 修改跟踪点的探针逻辑,在编译阶段直接将输出绑定到printk。以sched_switch跟踪点为例:
    原定义片段:
    TRACE_EVENT(sched_switch,
        TP_PROTO(struct task_struct *prev, struct task_struct *next),
        TP_ARGS(prev, next),
        TP_STRUCT__entry(
            __array(char, prev_comm, TASK_COMM_LEN)
            __field(pid_t, prev_pid)
            __array(char, next_comm, TASK_COMM_LEN)
            __field(pid_t, next_pid)
        ),
        TP_fast_assign(
            memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
            __entry->prev_pid = prev->pid;
            memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
            __entry->next_pid = next->pid;
        ),
        TP_printk("prev_comm=%s prev_pid=%d next_comm=%s next_pid=%d",
                  __entry->prev_comm, __entry->prev_pid,
                  __entry->next_comm, __entry->next_pid)
    );
    
    新增编译时生效的打印逻辑:
    #ifdef CONFIG_MY_TRACE_PRINT
    static void __always_inline trace_sched_switch_print(struct task_struct *prev, struct task_struct *next)
    {
        printk(KERN_INFO "sched_switch: prev_comm=%s prev_pid=%d next_comm=%s next_pid=%d\n",
               prev->comm, prev->pid, next->comm, next->pid);
    }
    #define TRACE_SCHED_SWITCH_PRINT() trace_sched_switch_print(prev, next)
    #else
    #define TRACE_SCHED_SWITCH_PRINT() do {} while(0)
    #endif
    
    然后在TP_fast_assign块内调用TRACE_SCHED_SWITCH_PRINT(),编译内核时添加CONFIG_MY_TRACE_PRINT=y配置即可生效。

方法3:利用内核静态跟踪与trace_printk

  • 开启内核配置CONFIG_TRACING=y和CONFIG_TRACE_PRINTK=y,trace_printk是轻量级的跟踪专用打印函数,效率优于普通printk。
  • 在跟踪点的探针逻辑中直接调用trace_printk,例如:
    TP_fast_assign(
        // 原有赋值逻辑
        trace_printk("sched_switch: prev=%s(%d), next=%s(%d)\n",
                     prev->comm, prev->pid, next->comm, next->pid);
    );
    
    编译后,这些输出会直接写入内核日志环缓冲区,无需运行时配置跟踪点。

注意事项

  • 修改内核代码或配置后,需重新编译内核并部署到目标系统。
  • 跟踪输出会增加内核日志负载,调试完成后记得关闭对应配置或移除相关代码,避免影响系统性能。
  • 若日志易被覆盖,可调整内核日志环缓冲区大小(如通过sysctl kernel.printk_ringbuffer_size,需系统允许)。

内容的提问来源于stack exchange,提问作者Siddharth Chandrasekaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:27:32