1. 程式人生 > >使用 ftrace 除錯 Linux 核心,第 1 部分-debugfs掛載和除錯介面

使用 ftrace 除錯 Linux 核心,第 1 部分-debugfs掛載和除錯介面

ftrace 是內建於 Linux 核心的跟蹤工具,從 2.6.27 開始加入主流核心。使用 ftrace 可以除錯或者分析核心中發生的事情。ftrace 提供了不同的跟蹤器,以用於不同的場合,比如跟蹤核心函式呼叫、對上下文切換進行跟蹤、檢視中斷被關閉的時長、跟蹤核心態中的延遲以及效能問題等。系統開發人員可以使用 ftrace 對核心進行跟蹤除錯,以找到核心中出現的問題的根源,方便對其進行修復。另外,對核心感興趣的讀者還可以通過 ftrace 來觀察核心中發生的活動,瞭解核心的工作機制。

讓核心支援 ftrace

使用 ftrace ,首先要將其編譯進核心。核心原始碼目錄下的 kernel/trace/Makefile 檔案給出了 ftrace 相關的編譯選項。

清單 1. ftrace 相關的配置選項列表
 CONFIG_FUNCTION_TRACER 
 CONFIG_FUNCTION_GRAPH_TRACER 
 CONFIG_CONTEXT_SWITCH_TRACER 
 CONFIG_NOP_TRACER 
 CONFIG_SCHED_TRACER 
 ...

ftrace 相關的配置選項比較多,針對不同的跟蹤器有各自對應的配置選項。不同的選項有不同的依賴關係,核心原始碼目錄下的 kernel/trace/Kconfig 檔案描述了這些依賴關係。讀者可以參考 Makefile 檔案和 Konfig 檔案,然後選中自己所需要的跟蹤器。

通常在配置核心時,使用 make menuconfig 會更直觀一些。以 2.6.33.1 版本的核心為例,要將 ftrace 編譯進核心,可以選中 Kernel hacking (圖 1 )下的 Tracers 選單項(圖 2 )。

圖 1. Kernel hacking
圖 1. Kernel hacking
圖 2. Tracers
圖 2. Tracers

進入 Tracers 選單下,可以看到核心支援的跟蹤器列表。如圖 3 所示,這裡選中了所有的跟蹤器,讀者可以根據自己的需要選中特定的跟蹤器。

圖 3. 核心支援的跟蹤器列表
圖 3. 核心支援的跟蹤器列表

這裡要注意,如果是在 32 位 x86 機器上,編譯時不要選中 General setup 選單項(圖 4 )下的 Optimize for size 選項(圖 5 ),否則就無法看到圖 3 中的 Kernel Function Graph Tracer 選項。這是因為在 Konfig 檔案中,針對 32 位 x86 機器,表項 FUNCTION_GRAPH_TRACER 有一個特殊的依賴條件:

        depends on !X86_32 || !CC_OPTIMIZE_FOR_SIZE
圖 4. General setup
圖 4. General setup
圖 5. Optimize for size
圖 5. Optimize for size

ftrace 通過 debugfs 向用戶態提供了訪問介面,所以還需要將 debugfs 編譯進核心。啟用對 debugfs 的支援,可以直接編輯核心配置檔案 .config ,設定 CONFIG_DEBUG_FS=y ;或者在 make menuconfig 時到 Kernel hacking 選單下選中對 debugfs 檔案系統的支援,如圖 6 所示。

圖 6. debugfs 編譯選項
圖 6. debugfs 編譯選項

配置完成後,編譯安裝新核心,然後啟動到新核心。 注意,啟用 ftrace 支援後,編譯核心時會使用編譯器的 -pg 選項,這是在 kernel/trace/Makefile 檔案中定義的,如清單 2 所示。

清單 2. 啟用編譯選項 -pg
 ifdef CONFIG_FUNCTION_TRACER 
 ORIG_CFLAGS := $(KBUILD_CFLAGS) 
 KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) 
 ... 
 endif 
 ...

使用 -pg 選項會在編譯得到的核心映像中加入大量的除錯資訊。一般情況下,只是在開發測試階段啟用 ftrace 支援,以除錯核心,修復 bug 。最終用於發行版的核心則會關閉 -pg 選項,也就無法使用 ftrace。

通過 debugfs 訪問 ftrace

ftrace 通過 debugfs 向用戶態提供訪問介面。配置核心時啟用 debugfs 後會建立目錄 /sys/kernel/debug ,debugfs 檔案系統就是掛載到該目錄。要掛載該目錄,需要將如下內容新增到 /etc/fstab 檔案:

        debugfs  /sys/kernel/debug  debugfs  defaults  0  0

或者可以在執行時掛載:

        mount  -t  debugfs  nodev  /sys/kernel/debug

啟用核心對 ftrace 的支援後會在 debugfs 下建立一個 tracing 目錄 /sys/kernel/debug/tracing 。該目錄下包含了 ftrace 的控制和輸出檔案,如圖 7 所示。根據編譯核心時針對 ftrace 的設定不同,該目錄下實際顯示的檔案和目錄與這裡也會不同。

圖 7. tracing 目錄下的檔案
圖 7. tracing 目錄下的檔案

ftrace 的資料檔案

/sys/kernel/debug/trace 目錄下檔案和目錄比較多,有些是各種跟蹤器共享使用的,有些是特定於某個跟蹤器使用的。在操作這些資料檔案時,通常使用 echo 命令來修改其值,也可以在程式中通過檔案讀寫相關的函式來操作這些檔案的值。下面只對部分檔案進行描述,讀者可以參考核心原始碼包中 Documentation/trace 目錄下的文件以及 kernel/trace 下的原始檔以瞭解其餘檔案的用途。

  • README檔案提供了一個簡短的使用說明,展示了 ftrace 的操作命令序列。可以通過 cat 命令檢視該檔案以瞭解概要的操作流程。
  • current_tracer用於設定或顯示當前使用的跟蹤器;使用 echo 將跟蹤器名字寫入該檔案可以切換到不同的跟蹤器。系統啟動後,其預設值為 nop ,即不做任何跟蹤操作。在執行完一段跟蹤任務後,可以通過向該檔案寫入 nop 來重置跟蹤器。
  • available_tracers記錄了當前編譯進核心的跟蹤器的列表,可以通過 cat 檢視其內容;其包含的跟蹤器與圖 3 中所啟用的選項是對應的。寫 current_tracer 檔案時用到的跟蹤器名字必須在該檔案列出的跟蹤器名字列表中。
  • trace檔案提供了檢視獲取到的跟蹤資訊的介面。可以通過 cat 等命令檢視該檔案以檢視跟蹤到的核心活動記錄,也可以將其內容儲存為記錄檔案以備後續檢視。
  • tracing_enabled用於控制 current_tracer 中的跟蹤器是否可以跟蹤核心函式的呼叫情況。寫入 0 會關閉跟蹤活動,寫入 1 則啟用跟蹤功能;其預設值為 1 。
  • set_graph_function設定要清晰顯示呼叫關係的函式,顯示的資訊結構類似於 C 語言程式碼,這樣在分析核心運作流程時會更加直觀一些。在使用 function_graph 跟蹤器時使用;預設為對所有函式都生成呼叫關係序列,可以通過寫該檔案來指定需要特別關注的函式。
  • buffer_size_kb用於設定單個 CPU 所使用的跟蹤快取的大小。跟蹤器會將跟蹤到的資訊寫入快取,每個 CPU 的跟蹤快取是一樣大的。跟蹤快取實現為環形緩衝區的形式,如果跟蹤到的資訊太多,則舊的資訊會被新的跟蹤資訊覆蓋掉。注意,要更改該檔案的值需要先將 current_tracer 設定為 nop 才可以。
  • tracing_on用於控制跟蹤的暫停。有時候在觀察到某些事件時想暫時關閉跟蹤,可以將 0 寫入該檔案以停止跟蹤,這樣跟蹤緩衝區中比較新的部分是與所關注的事件相關的;寫入 1 可以繼續跟蹤。
  • available_filter_functions記錄了當前可以跟蹤的核心函式。對於不在該檔案中列出的函式,無法跟蹤其活動。
  • set_ftrace_filter和 set_ftrace_notrace在編譯核心時配置了動態 ftrace (選中 CONFIG_DYNAMIC_FTRACE 選項)後使用。前者用於顯示指定要跟蹤的函式,後者則作用相反,用於指定不跟蹤的函式。如果一個函式名同時出現在這兩個檔案中,則這個函式的執行狀況不會被跟蹤。這些檔案還支援簡單形式的含有萬用字元的表示式,這樣可以用一個表示式一次指定多個目標函式;具體使用在後續文章中會有描述。注意,要寫入這兩個檔案的函式名必須可以在檔案 available_filter_functions 中看到。預設為可以跟蹤所有核心函式,檔案 set_ftrace_notrace 的值則為空。

ftrace 跟蹤器

ftrace 當前包含多個跟蹤器,用於跟蹤不同型別的資訊,比如程序排程、中斷關閉等。可以檢視檔案 available_tracers 獲取核心當前支援的跟蹤器列表。在編譯核心時,也可以看到核心支援的跟蹤器對應的選項,如之前圖 3 所示。

  • nop跟蹤器不會跟蹤任何核心活動,將 nop 寫入 current_tracer 檔案可以刪除之前所使用的跟蹤器,並清空之前收集到的跟蹤資訊,即重新整理 trace 檔案。
  • function跟蹤器可以跟蹤核心函式的執行情況;可以通過檔案 set_ftrace_filter 顯示指定要跟蹤的函式。
  • function_graph跟蹤器可以顯示類似 C 原始碼的函式呼叫關係圖,這樣檢視起來比較直觀一些;可以通過檔案 set_grapch_function 顯示指定要生成呼叫流程圖的函式。
  • sched_switch跟蹤器可以對核心中的程序排程活動進行跟蹤。
  • irqsoff跟蹤器和 preemptoff跟蹤器分別跟蹤關閉中斷的程式碼和禁止程序搶佔的程式碼,並記錄關閉的最大時長,preemptirqsoff跟蹤器則可以看做它們的組合。

ftrace 還支援其它一些跟蹤器,比如 initcall、ksym_tracer、mmiotrace、sysprof 等。ftrace 框架支援擴充套件新增新的跟蹤器。讀者可以參考核心原始碼包中 Documentation/trace 目錄下的文件以及 kernel/trace 下的原始檔,以瞭解其它跟蹤器的用途和如何新增新的跟蹤器。

小結

本系列文章對 ftrace 的配置和使用進行了介紹。本文是其中的第一部分,介紹了 ftrace 的編譯配置、使用者態訪問 ftrace 的介面和 ftrace 的資料檔案,並對 ftrace 所提供的部分跟蹤器的用途進行了描述。由於篇幅的限制,本文沒有對 ftrace 的具體使用和如何在程式碼中與 ftrace 進行互動進行描述,這些內容將分別在本系列文章的後續篇章中給出。

文章連結:

http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1/index.html?ca=drs-