Linux ftrace 內核跟蹤入門

文章目錄

    • ftrace介紹
    • 開啟ftrace
    • ftrace使用
      • ftrace跟蹤指定內核函數
      • ftrace跟蹤指定pid
    • ftrace原理
    • ftrace與strace
    • trace-cmd 工具
    • KernelShark
    • 參考

ftrace介紹

Ftrace is an internal tracer designed to help out developers and designers of systems to find what is going on inside the kernel. It can be used for debugging or analyzing latencies and performance issues that take place outside of user-space.

ftrace 是內建于 Linux 內核的跟蹤工具,從 2.6.27 開始加入主流內核。使用 ftrace 可以調試或者分析內核中發生的事情。ftrace 提供了不同的跟蹤器,以用于不同的場合,比如跟蹤內核函數調用、對上下文切換進行跟蹤、查看中斷被關閉的時長、跟蹤內核態中的延遲以及性能問題等。系統開發人員可以使用 ftrace 對內核進行跟蹤調試,以找到內核中出現的問題的根源,方便對其進行修復。

使用環境:Linux linuxdev 6.8.0-52-generic #53-Ubuntu SMP PREEMPT_DYNAMIC Sat Jan 11 00:06:25 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

開啟ftrace

一般的linux發行版都已經開啟了ftrace支持,
在這里插入圖片描述
最基礎的是這幾個選項:

  • CONFIG_FTRACE --> “Tracers”
  • CONFIG_FUNCTION_TRACER --> Kernel Function Tracer
  • CONFIG_FUNCTION_GRAPH_TRACER --> Kernel Function Graph Tracer
  • CONFIG_DYNAMIC_FTRACE --> enable/disable function tracing dynamically

更多的選項可以查看內核trace模塊的makefile和kconfig文件:kernel/trace/Makefilekernel/trace/Kconfig

ftrace 使用 tracefs 文件系統來保存控制文件以及用于顯示輸出的文件,啟用ftrace功能后,默認會掛載出來,目前的環境上是在:tracefs /sys/kernel/tracing tracefs rw,nosuid,nodev,noexec,relatime 0 0

查看tracefs掛載點下面的內容:

$ sudo ls /sys/kernel/tracing
available_events                  current_tracer            hwlat_detector   printk_formats         set_event_pid           stack_max_size      trace_marker         tracing_thresh
available_filter_functions        dynamic_events            instances        README                 set_ftrace_filter       stack_trace         trace_marker_raw     uprobe_events
available_filter_functions_addrs  dyn_ftrace_total_info     kprobe_events    rv                     set_ftrace_notrace      stack_trace_filter  trace_options        uprobe_profile
available_tracers                 enabled_functions         kprobe_profile   saved_cmdlines         set_ftrace_notrace_pid  synthetic_events    trace_pipe           user_events_data
buffer_percent                    error_log                 max_graph_depth  saved_cmdlines_size    set_ftrace_pid          timestamp_mode      trace_stat           user_events_status
buffer_size_kb                    events                    options          saved_tgids            set_graph_function      touched_functions   tracing_cpumask
buffer_subbuf_size_kb             free_buffer               osnoise          set_event              set_graph_notrace       trace               tracing_max_latency
buffer_total_size_kb              function_profile_enabled  per_cpu          set_event_notrace_pid  snapshot                trace_clock         tracing_on

tracing目錄(/sys/kernel/tracing)中的文件控制著跟蹤的能力。根據你在內核配置時的選項的不同,這里列的文件可能稍有差異。你可以在內核源代碼目錄下Documentation/trace目錄中找到這些文件的信息。

下面介紹幾個重要的文件:

  • available_tracers
    該文件列出所有當前內核支持的tracer
# cat available_tracers
timerlat osnoise hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
  • current_tracer
    該文件指出當前正在運行的tracer
# cat current_tracer 
nop
  • trace -> Contains the tracing data in human readable format
    該文件包含可閱讀的tracing數據
# cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 0/0   #P:4
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
  • tracing_on
    該文件開啟/關閉輸出tracing數據到ring buffer(ftrace使用單獨的ring buffer來存儲tracing數據)
# cat tracing_on 
1

ftrace使用

ftrace一般使用步驟:

  1. 寫入一些特定文件以啟用 / 禁用tracing。
  2. 寫入一些特定文件以設置 / 取消設置過濾器以微調tracing。
  3. 根據步驟 1 和 2 從文件中讀取生成的tracing輸出。
  4. 清除文件中的早期輸出或緩沖區。
  5. 縮小到你的特定用例(要跟蹤的內核函數)并重復步驟 1、2、3、4。

指定某個tracer,我們只要將該tracer的名稱寫入current_tracer文件。

# echo function > current_tracer

隨后我們可以通過trace或者trace_pipe文件讀取輸出

# cat trace | head -20
# tracer: function
#
# entries-in-buffer/entries-written: 205023/41961107   #P:4
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |mintreport-tray-6561    [003] ...1. 23204.688260: seq_put_decimal_ull_width <-seq_put_decimal_ullmintreport-tray-6561    [003] ...1. 23204.688260: seq_put_decimal_ull <-do_task_statmintreport-tray-6561    [003] ...1. 23204.688260: seq_put_decimal_ull_width <-seq_put_decimal_ullmintreport-tray-6561    [003] ...1. 23204.688260: seq_put_decimal_ull <-do_task_stat
##### CPU 2 buffer started ####<idle>-0       [002] d.h2. 23204.749361: __sysvec_apic_timer_interrupt <-sysvec_apic_timer_interrupt<idle>-0       [002] d.h2. 23204.749362: hrtimer_interrupt <-__sysvec_apic_timer_interrupt<idle>-0       [002] d.h2. 23204.749362: _raw_spin_lock_irqsave <-hrtimer_interrupt

如果你想關閉該tracer,直接將nop寫入current_tracer文件即可。

function_graph是一種替代的函數跟蹤器,它不僅跟蹤函數入口,還跟蹤函數的返回,允許你創建函數流的調用圖,并以類似 C 語言的風格輸出跟蹤數據,其中包含每個函數的持續時間信息。

# cat trace | head -20
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |2)   0.151 us    |                } /* seq_printf */2)   0.152 us    |                seq_printf();2)   0.152 us    |                seq_printf();2)   0.149 us    |                seq_printf();2)   0.112 us    |                _raw_spin_lock_irqsave();2)   0.153 us    |                seq_printf();2)   0.160 us    |                seq_printf();2)   0.159 us    |                seq_printf();2)   0.153 us    |                seq_printf();2)   0.156 us    |                seq_printf();2)   0.111 us    |                seq_putc();2)   0.112 us    |                _raw_spin_unlock_irqrestore();2)   0.117 us    |                __rcu_read_unlock();2)   4.759 us    |              } /* show_interrupts */2)   0.109 us    |              int_seq_next();2)   0.109 us    |              int_seq_stop();

ftrace跟蹤指定內核函數

available_filter_functions文件展示了ftrace支持的跟蹤內核函數的集合,我們可以從這里尋找需要跟蹤的內核函數,或者自己指定。

# grep fork available_filter_functions
ret_from_fork
__do_sys_fork
__do_sys_vfork
tsk_fork_get_node
__traceiter_sched_process_fork
__probestub_sched_process_fork
__sched_fork
sched_fork
sched_cgroup_fork
sched_post_fork
sched_mm_cid_fork
task_fork_fair
task_fork_dl
sched_core_fork
sched_autogroup_fork
timens_on_fork
cgroup_css_set_put_fork
cgroup_fork
cgroup_cancel_fork
cgroup_post_fork
cgroup_css_set_fork
cgroup_can_fork
freezer_fork
pids_cancel_fork
pids_can_fork
cpuset_cancel_fork
cpuset_can_fork
cpuset_fork
perf_event_fork
anon_vma_fork
mem_cgroup_fork
tty_audit_fork
register_random_vmfork_notifier
unregister_random_vmfork_notifier
add_vmfork_randomness
proc_fork_connector

嘗試跟蹤__do_sys_fork函數,很遺憾目前環境中的內核在創建進程時不使用該函數,而是使用kernel_clone這個函數

#ifdef __ARCH_WANT_SYS_FORK
SYSCALL_DEFINE0(fork)
{
#ifdef CONFIG_MMUstruct kernel_clone_args args = {.exit_signal = SIGCHLD,};return kernel_clone(&args);
#else/* can not support in nommu mode */return -EINVAL;
#endif
}
#endif

查找該函數:

# grep kernel_clone /sys/kernel/tracing/available_filter_functions
kernel_clone

跟蹤該函數:

root@linuxdev:/sys/kernel/tracing# echo nop >current_tracer 
root@linuxdev:/sys/kernel/tracing# echo kernel_clone>set_graph_function 
root@linuxdev:/sys/kernel/tracing# echo function_graph >current_tracer 
root@linuxdev:/sys/kernel/tracing# cat trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |0)               |  kernel_clone() {0) # 1520.654 us |    copy_process();0)   2.568 us    |    add_device_randomness();0)   1.289 us    |    get_task_pid();0)   0.757 us    |    pid_vnr();0)   0.673 us    |    _raw_spin_lock();0)   3.660 us    |    lru_gen_add_mm();0)   0.690 us    |    _raw_spin_unlock();0) + 47.696 us   |    wake_up_new_task();0)   1.016 us    |    put_pid();0) # 1592.533 us |  }1)               |  ret_from_fork() {1) ! 122.284 us  |    schedule_tail();1)   0.859 us    |    syscall_exit_to_user_mode_prepare();1)   0.638 us    |    mem_cgroup_handle_over_high();1)   0.666 us    |    blkcg_maybe_throttle_current();1) + 60.708 us   |    __rseq_handle_notify_resume();1)   0.768 us    |    fpregs_assert_state_consistent();1)   1.831 us    |    switch_fpu_return();1) ! 197.731 us  |  }3)               |  kernel_clone() {3) # 1391.121 us |    copy_process();3)   2.695 us    |    add_device_randomness();3)   1.232 us    |    get_task_pid();3)   0.783 us    |    pid_vnr();3)   0.669 us    |    _raw_spin_lock();3)   3.709 us    |    lru_gen_add_mm();3)   0.654 us    |    _raw_spin_unlock();3) + 54.441 us   |    wake_up_new_task();3)   1.083 us    |    put_pid();3) # 1469.054 us |  }------------------------------------------0)   bash-7769    =>    cat-8888   ------------------------------------------0)               |  ret_from_fork() {0) + 69.115 us   |    schedule_tail();0)   0.804 us    |    syscall_exit_to_user_mode_prepare();0)   0.689 us    |    mem_cgroup_handle_over_high();0)   0.677 us    |    blkcg_maybe_throttle_current();0) + 37.261 us   |    __rseq_handle_notify_resume();0)   0.756 us    |    fpregs_assert_state_consistent();0)   1.950 us    |    switch_fpu_return();0) ! 120.873 us  |  }

ftrace跟蹤指定pid

# echo $PID > set_ftrace_pid

以監控top進程為例:

# pidof top
8963
# echo 8963 > set_ftrace_pid
# cat trace | head -30
# tracer: function
#
# entries-in-buffer/entries-written: 13655/8126400   #P:4
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |top-8963    [001] d..2. 27383.603413: <stack trace>=> 0xffffffffc12840ad=> _raw_spin_unlock=> finish_task_switch.isra.0=> __schedule=> __cond_resched=> mutex_lock=> process_output_block=> n_tty_write=> iterate_tty_write=> file_tty_write.isra.0=> tty_write=> vfs_write=> ksys_write=> __x64_sys_write=> x64_sys_call=> do_syscall_64=> entry_SYSCALL_64_after_hwframe

需要注意的是每次進行新的tracing的時候需要清除下上一次tracing的配置,如果上次設置了某些過濾條件,那么可能會對本次的tracing結果產生影響

更進一步的使用建議參考Debugging Linux Kernel using ftrace著一系列文章。

ftrace原理

參考Ftrace 實現原理與開發實踐
在這里插入圖片描述

ftrace與strace

參考Ftrace 實現原理與開發實踐
在這里插入圖片描述
他們的底層原理不同,表現出來的區別是ftrace可以跟蹤內核中的函數,而strace只能跟蹤到系統函數調用。

strace is a utility which allows you to trace the system calls that an application makes. When an application makes a system call, it is basically asking the kernel to do something, eg file access. Use the command man strace to get strace documentation and man syscalls to get information on system calls.
ftrace is a tool used during kernel development and allows the developer to see what functions are being called within the kernel.

參考這張著名的linux性能分析工具圖:
在這里插入圖片描述

trace-cmd 工具

trace-cmd工具是Steven Rostedt創建的用于ftrace的命令行工具。

KernelShark

KernelShark是一個圖形工具,作為一個前端來處理trace-cmd工具生成的tracing數據——trace.dat。

參考

ftrace - Function Tracer
Debugging Linux Kernel using ftrace
Analyze the Linux kernel with ftrace
從Ftrace開始內核探索之旅
Tracing the Linux kernel with ftrace
Debugging the kernel using Ftrace - part 1
Debugging the kernel using Ftrace - part 2
Secrets of the Ftrace function tracer
Using KernelShark to analyze the real-time scheduler
Ftrace Kernel Hooks: More than just tracing
ftrace系統實現原理
Linux性能工具(二)ftrace基礎篇
linux性能分析工具–ftrace的原理與使用
Linux內核性能調試工具之ftrace
Ftrace 實現原理與開發實踐

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/68209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/68209.shtml
英文地址,請注明出處:http://en.pswp.cn/web/68209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【抽象代數】1.1. 運算及關系

集合與映射 定義1. 設 為 的子集&#xff0c;定義 到 的映射 &#xff1a; 使得 &#xff0c;稱 為 到 的嵌入映射。 定義2. 設 為 的子集&#xff0c; 為 到 的映射&#xff0c; 為 到 的映射&#xff0c;如果 &#xff0c;稱為的開拓&#xff0c; 為 的限制&…

pytest+request+yaml+allure 接口自動化測試全解析[手動寫的跟AI的對比]

我手動寫的:Python3:pytest+request+yaml+allure接口自動化測試_request+pytest+yaml-CSDN博客 AI寫的:pytest+request+yaml+allure 接口自動化測試全解析 在當今的軟件開發流程中,接口自動化測試扮演著至關重要的角色。它不僅能夠提高測試效率,確保接口的穩定性和正確性…

數據庫高安全—審計追蹤:傳統審計統一審計

書接上文數據庫高安全—角色權限&#xff1a;權限管理&權限檢查&#xff0c;從權限管理和權限檢查方面解讀了高斯數據庫的角色權限&#xff0c;本篇將從傳統審計和統一審計兩方面對高斯數據庫的審計追蹤技術進行解讀。 4 審計追蹤 4.1 傳統審計 審計內容的記錄方式通…

第三個Qt開發實例:利用之前已經開發好的LED驅動在Qt生成的界面中控制LED2的亮和滅

前言 上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145459006 中&#xff0c;我們是直接利用GPIO子系統控制了LED2的亮和滅&#xff0c;這篇博文中我們利用之前寫好的LED驅動程序在Qt的生成的界面中控制LED2的亮和滅。 之前已經在下面兩篇博文中實現了LED驅動…

deepseek來講lua

Lua 是一種輕量級、高效、可嵌入的腳本語言&#xff0c;廣泛應用于游戲開發、嵌入式系統、Web 服務器等領域。以下是 Lua 的主要特點和一些基本概念&#xff1a; 1. 特點 輕量級&#xff1a;Lua 的核心非常小&#xff0c;適合嵌入到其他應用程序中。高效&#xff1a;Lua 的執…

(動態規劃 leetcode377)組合求和IV

確立狀態轉移方程需要深入理解問題&#xff0c;合理定義子問題&#xff0c;找到邊界條件(比如dp[0])&#xff0c;分析狀態之間的轉移關系&#xff08;dp和dp之間的關系&#xff09;&#xff0c;并進行驗證。 遞歸是自頂向下&#xff0c;而dp是自下而上 這里是i作為目標值&…

解決aspose將Excel轉成PDF中文變成方框的亂碼問題

原文網址&#xff1a;解決aspose將Excel轉成PDF中文變成方框的亂碼問題_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹如何解決aspose將Excel轉成PDF中文變成方框的亂碼問題。 問題描述 用aspose將word、excel等轉成PDF后&#xff0c;英文展示正常&#xff0c;但中文全部變成了…

Netty 核心原理與高并發場景實踐

在當今的網絡編程領域&#xff0c;隨著互聯網應用的不斷發展&#xff0c;對高并發、高性能網絡通信的需求日益增長。Netty 作為一款基于 Java 的異步事件驅動的網絡應用框架&#xff0c;憑借其卓越的性能和豐富的功能&#xff0c;成為了實現高并發網絡應用的首選工具。無論是在…

問題大集04-瀏覽器阻止從 本地 發起的跨域請求,因為服務器的響應頭 Access-Control-Allow-Origin 設置為通配符 *

1、問題 localhost/:1 Access to XMLHttpRequest at xxx&#xff08;請求&#xff09; from origin http://localhost:xxx&#xff08;本地&#xff09; has been blocked by CORS policy: The value of the Access-Control-Allow-Origin header in the response must not be t…

判斷192.168.1.0/24網絡中,當前在線的ip有哪些

需求&#xff1a;判斷192.168.1.0/24網絡中&#xff0c;當前在線的ip有哪些&#xff0c;并編寫腳本打印出來。 [rootopenEuler ~]# cat 1.sh #!/bin/bash for ip in $(seq 1 254); do ping -c 1 -W 1 "192.168.1.$ip" > /dev/null 2>&1 if [ $? …

vue-vite axios bug

axios-bug http proxy error Error: write ECONNABORTED 代碼寫法 一般baseURL不是單寫前綴就可以了嗎&#xff0c;為何要寫死就不會出現以上錯誤&#xff0c;求解。

【Spring】_SpringBoot配置文件

目錄 1.Spring Boot配置文件 1.1 Spring Boot 的配置文件類型及命名 1.2 properties和yml的優先級 2. properties配置文件 1.1 properties語法格式 1.2 自定義配置及配置文件的讀取 1.3 properties的缺點 3. yml配置文件 3.1 yml語法格式 3.2 自定義配置及配置文件的…

實操給觸摸一體機接入大模型語音交互

本文以CSK6 大模型開發板串口觸摸屏為例&#xff0c;實操講解觸摸一體機怎樣快速增加大模型語音交互功能&#xff0c;使用戶能夠通過語音在一體機上查詢信息、獲取智能回答及實現更多互動功能等。 在本文方案中通過CSK6大模型語音開發板采集用戶語音&#xff0c;將語音數據傳輸…

深入解析 FFmpeg 的 AAC 編解碼過程

深入解析 FFmpeg 的 AAC 編解碼過程 —— 技術詳解與代碼實現 AAC(Advanced Audio Coding) 是一種高效的有損音頻壓縮格式,因其高壓縮效率和良好的音質而被廣泛應用于流媒體、廣播和音頻存儲等領域。FFmpeg 是一個強大的多媒體處理工具,支持 AAC 的編碼和解碼。本文將詳細…

RabbitMQ 從入門到精通:從工作模式到集群部署實戰(一)

#作者&#xff1a;閆乾苓 文章目錄 RabbitMQ簡介RabbitMQ與VMware的關系架構工作流程RabbitMQ 隊列工作模式及適用場景簡單隊列模式&#xff08;Simple Queue&#xff09;工作隊列模式&#xff08;Work Queue&#xff09;發布/訂閱模式&#xff08;Publish/Subscribe&#xff…

探索 Spring Cloud Alibaba:開啟微服務架構新時代

一、引言 在當今數字化浪潮中&#xff0c;軟件系統的規模和復雜度不斷攀升&#xff0c;傳統的單體架構逐漸難以滿足快速迭代、高并發處理以及靈活擴展的需求。微服務架構應運而生&#xff0c;它將一個大型的應用拆分成多個小型、自治的服務&#xff0c;每個服務專注于特定的業務…

Linux基礎命令之Nginx中的rewrite功能(重新)

一、什么是Rewrite Rewrite也稱URL Rewrite&#xff0c;即URL重寫&#xff0c;就是把傳入Web的請求重定向到其他URL的過程。 1. URL Rewrite最常見的應用是URL偽靜態化&#xff0c;是將動態頁面顯示為靜態頁面方式的一種技術。比如http://www.123.com/news/index.php?id123 使…

anaconda使用

anaconda配置鏡像源&#xff1a; 引用&#xff1a;https://zhuanlan.zhihu.com/p/17776864328 # 顯示所有的鏡像源 conda config --show channels # 設置鏡像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add c…

DeepSeek 闡述 2025年前端發展趨勢

預測2025年前端的發展趨勢。首先&#xff0c;我需要考慮當前的前端 技術發展情況&#xff0c;以及近幾年的變化趨勢。比如&#xff0c;框架方面&#xff0c;React、Vue、Angular這些主流框架的更新方向和社區活躍度。可能用戶想知道未來哪些技術會更流行&#xff0c;或者需要學…

RK3568平臺開發系列講解(ConfigFS篇)ConfigFS核心數據結構

??返回專欄總目錄 文章目錄 一、數據結構二、結構體關系三、案例3.1、configfs_subsystem 實例3.2、config_group 實例化四、屬性和方法五、config_item實例化沉淀、分享、成長,讓自己和他人都能有所收獲!?? 理解 ConfigFS 的核心數據結構對于深入使用和定制 ConfigFS 非…