Linux(ftrace)__mcount的實現原理

Linux 內核調試工具ftrace 之(_mcount的實現原理)

ftrace 是 Linux 內核中的一種跟蹤工具,主要用于性能分析、調試和內核代碼的執行跟蹤。它通過在內核代碼的關鍵點插入探針(probe)來記錄函數調用和執行信息。這對于開發者排查問題、優化性能或者理解內核行為非常有用。

linux中主要支持兩種ftrace的實現方式:

  1. _mcount機制,(主要在內核為5.10前版本)
  2. NOP指令動態插樁機制(主要在內核為5.10及以后版本),見文章《ftrace之雙nop機制實現原理》

下面將分別深入介紹兩種機制的實現原理:

一、_mcount機制的實現

 * Gcc with -pg will put the following code in the beginning of each function:*      mov x0, x30*      bl _mcount*	[function's body ...]* "bl _mcount" may be replaced to "bl ftrace_caller" or NOP if dynamic* ftrace is enabled.
  • gcc編譯內核時加上 -pg 選項將會在每個支持被插樁的函數前面插入mov x0, x30bl _mcount指令。
  • 如果開啟了動態插樁,那bl _mcount會被bl ftrace_callerNOP指令替換,當需要對該函數進行追蹤時,將重新插入bl _mcount,取消追蹤時會重新替換為bl ftrace_callerNOP指令。這樣會降低ftrace對性能的損耗。

_mcount入口的分析

  1. 下面是實際的編譯的驅動函數匯編代碼:
    _mcount被插樁在函數的b74地址處(同樣mov x0, x30也被插樁)。
0000000000000b58 <pcie_adc_ioctl>:b58:       a9bd7bfd        stp     x29, x30, [sp, #-48]!b5c:       910003fd        mov     x29, spb60:       a90153f3        stp     x19, x20, [sp, #16]b64:       d50320ff        xpaclrib68:       2a0103f4        mov     w20, w1b6c:       aa1e03e0        mov     x0, x30b70:       aa0203f3        mov     x19, x2b74:       94000000        bl      0 <_mcount>b78:       90000000        adrp    x0, 0 <__stack_chk_guard>b7c:       f9400001        ldr     x1, [x0]b80:       f90017e1        str     x1, [sp, #40]
  1. 插樁的兩條指令并不是插入在函數的最前面第一、二地址處,而是在該函數將該函數的棧分配好以及保存好現場后再進行插樁。
  • 下述的三點是編譯器默認的規定(x0-x8 and x18-x30 are live (x18 holds the Shadow Call Stack pointer), and x9-x17 are safe to clobber.)即:
    • 將父函數的FP、父函數的返回地址lr入棧(即x29x30)。
      • stp x29, x30, [sp, #-48]!保護FPlr以及函數棧的分配
    • x18~x28中后續函數體要用到的寄存器進行入棧保存,如果用不到則不用入棧保存
      • stp x19, x20, [sp, #16]
    • 如果x0~x7中為函數傳參則也需要將對應的寄存器進行保存(一般保存到x18~x26寄存器中),參數的傳遞一般是前8個參數由x0~x7寄存器,后面的參數都有棧進行傳遞。所以在被調用函數中如果要用到調用者傳入的寄存器中的參數就需要保存。
      • mov w20, w1
      • mov x19, x2
      • 由于在該函數中并沒有用到第一個參數,所以編譯器就進行優化了,沒有進行x0寄存器值保存。
  • 在上面的現場保存后函數棧的分布如下圖:

在這里插入圖片描述

  1. 然后跳轉到_mcount
.macro mcount_enterstp	x29, x30, [sp, #-16]!mov	x29, sp
.endm
SYM_FUNC_START(_mcount)mcount_enterldr_l	x2, ftrace_trace_functionadr	x0, ftrace_stubcmp	x0, x2			// if (ftrace_trace_functionb.eq	skip_ftrace_call	//     != ftrace_stub) {mcount_get_pc	x0		//       function's pcmcount_get_lr	x1		//       function's lr (= parent's pc)blr	x2			//   (*ftrace_trace_function)(pc, lr);skip_ftrace_call:			// }
#ifdef CONFIG_FUNCTION_GRAPH_TRACERldr_l	x2, ftrace_graph_returncmp	x0, x2			//   if ((ftrace_graph_returnb.ne	ftrace_graph_caller	//        != ftrace_stub)ldr_l	x2, ftrace_graph_entry	//     || (ftrace_graph_entryadr_l	x0, ftrace_graph_entry_stub //     != ftrace_graph_entry_stub))cmp	x0, x2b.ne	ftrace_graph_caller	//     ftrace_graph_caller();
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */mcount_exit
SYM_FUNC_END(_mcount)
  • 進去也是對x29, x30(FP 和 LR)進行保存(FP為棧基指針)

  • 這時候的棧分布如下圖:

在這里插入圖片描述

  • mcount_get_pc x0指令取到追蹤函數B的地址的分析:
    • mcount_get_pc x0 -> ldr x0, [x29, #8]可以看出是FP_M + 8的地址處的值給x0,即LR_B給到x0,剛好LR_B就是B中bl _mcount指令下一條指令地址。
  • mcount_get_lr x1指令取到調用者函數的地址的分析:
    • mcount_get_lr x1 -> ldr x1, [x29] 以及 ldr x1, [x1, #8],可以看出第一條指令ldr x1, [x29]從FP_M的地址處取到內容FP_B存到x1中,然后第二條指令ldr x1, [x1, #8]從x1 + 8(= FP_B + 8)地址處取到內容LR_A給到x1,這樣就取到了A的LR地址,即調用者函數的返回地址。
  1. 經過上面的分析可以看到對于調用者A以及被追蹤者B函數的內容以及返回地址都可以拿到并保存。
  2. 接下來就是進入對應的追蹤器執行。
    1. 保存必要的信息,比如LR_A、LR_B、FP_A、FP_B等,并做其他ftrace的信息處理,然后將BL到LR_B中繼續執行完B函數(進入B函數時LR寄存器的地址為實際trace回調函數中的地址)。
    2. 當B函數執行完后,返回到trace回調函數,在trace函數中做該被追蹤函數B的記錄結尾,然后將直接返回到函數A繼續執行了。
  3. 對于超過8個參數的參數讀取也不受限制,直接通過父函數的FP指針訪問(并沒有破壞該函數的棧)。
    至此bl _mcount機制的實現原理已經解釋完,其他的就是對ftrace具體回調函數中的一些工作,這里就不再說明(主要是記錄函數調用運行的一些信息,并放入到ring buf中,開放應用層接口供應用層查看)。大致跳轉流程圖如下:

在這里插入圖片描述

具體的ftrace操作

見文章《ftrace-內核調試工具》

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

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

相關文章

Java注解(Annotation)

一、注解的定義 核心概念 注解是Java中一種特殊形式的“元數據”&#xff0c;用于為類、方法、字段、參數等代碼元素附加說明信息。它不會直接影響代碼邏輯&#xff0c;但可以通過編譯器、框架或反射機制進行解析和處理。 與注釋&#xff08;Comment&#xff09;的區別 注釋&a…

tauri2+typescript+vue+vite+leaflet等的簡單聯合使用(一)

項目目標 主要的目的是學習tauri。 流程 1、搭建項目 2、簡單的在項目使用leaflet 3、打包 準備項目 環境準備 廢話不多說&#xff0c;直接開始 需要有準備能運行Rust的環境和Node&#xff0c;對于Rust可以參考下面這位大佬的文章&#xff0c;Node不必細說。 Rust 和…

深入解析 Svelte:下一代前端框架的革命

深入解析 Svelte&#xff1a;下一代前端框架的革命 1. Svelte 簡介 Svelte 是一款前端框架&#xff0c;與 React、Vue 等傳統框架不同&#xff0c;它采用 編譯時&#xff08;Compile-time&#xff09; 方式來優化前端應用。它不像 React 或 Vue 依賴虛擬 DOM&#xff0c;而是…

關于流水線的理解

還是不太理解&#xff0c;我之前一直以為&#xff0c;對axis總線&#xff0c;每一級的寄存器就像fifo一樣&#xff0c;一級一級的分級存儲最后一級需要的數據。 像這張圖&#xff0c;一開始是在解析axis流形式的數據包&#xff0c;數據包一直都能輸入&#xff0c;所以valid一直…

Python代碼之美:從規范到藝術

基礎規范&#xff1a;代碼的"顏值"很重要 &#x1f449;大禮包&#x1f381;&#xff1a;&#x1f448; PEP 8&#xff1a;不只是規范&#xff0c;是寫作藝術 良好的代碼格式就像優美的書法&#xff0c;讓人賞心悅目。比如&#xff1a; # 不推薦的寫法 def calcul…

【AI+智造】在阿里云Ubuntu 24.04上部署DeepSeek R1 14B的完整方案

作者&#xff1a;Odoo技術開發/資深信息化負責人 日期&#xff1a;2025年2月28日 一、部署背景與目標 DeepSeek R1作為國產大語言模型的代表&#xff0c;憑借其強化學習驅動的推理能力&#xff0c;在復雜任務&#xff08;如數學問題、編程邏輯&#xff09;中表現優異。本地化部…

8 SpringBoot進階(上):AOP(面向切面編程技術)、AOP案例之統一操作日志

文章目錄 前言1. AOP基礎1.1 AOP概述: 什么是AOP?1.2 AOP快速入門1.3 Spring AOP核心中的相關術語(面試)2. AOP進階2.1 通知類型2.1.1 @Around:環繞通知,此注解標注的通知方法在目標方法前、后都被執行(通知的代碼在業務方法之前和之后都有)2.1.2 @Before:前置通知,此…

【react】快速上手基礎教程

目錄 一、React 簡介 1.什么是 React 2.React 核心特性 二、環境搭建 1. 創建 React 項目 2.關鍵配置 三、核心概念 1. JSX 語法 表達式嵌入 樣式處理 2. 組件 (Component) 3. 狀態 (State) 與屬性 (Props) 4. 事件處理 合成事件&#xff08;SyntheticEvent) 5. …

七星棋牌 6 端 200 子游戲全開源修復版源碼(樂豆 + 防沉迷 + 比賽場 + 控制)

七星棋牌源碼 是一款運營級的棋牌產品&#xff0c;覆蓋 湖南、湖北、山西、江蘇、貴州 等 6 大省區&#xff0c;支持 安卓、iOS 雙端&#xff0c;并且 全開源。這個版本是 修復優化后的二開版本&#xff0c;新增了 樂豆系統、比賽場模式、防沉迷機制、AI 智能控制 等功能&#…

【人工智能】Deepseek 與 Kimi 聯袂:重塑 PPT 創作,開啟智能演示新紀元

我的個人主頁 我的專欄&#xff1a;人工智能領域、java-數據結構、Javase、C語言&#xff0c;希望能幫助到大家&#xff01;&#xff01;&#xff01;點贊&#x1f44d;收藏? 前言 在當今快節奏的工作與學習場景中&#xff0c;PPT 制作常常是一項耗時耗力的任務。從前期的資…

Kafka的高水位、低水位是什么概念?

Kafka 的 高水位&#xff08;High Watermark, HW&#xff09; 和 低水位&#xff08;Low Watermark, LW&#xff09; 是和數據存儲、消費進度、日志清理等密切相關的重要概念。我們用一個 “蓄水池” 的比喻來形象地解釋它們的作用。 1. Kafka 里的數據像一個蓄水池 Kafka 的數…

基于JAVA+Spring+mysql_快遞管理系統源碼+設計文檔

文末獲取源碼數據庫文檔 感興趣的可以先收藏&#xff0c;有畢設問題&#xff0c;項目以及論文撰寫等問題都可以和博主溝通&#xff0c;盡最大努力幫助更多的人&#xff01; 摘 要 隨著物流行業信息化的深入使得物流過程中貨物的狀態和變化透明化&#xff0c;現代信息化的接入使…

Python----數據分析(Numpy:安裝,數組創建,切片和索引,數組的屬性,數據類型,數組形狀,數組的運算,基本函數)

一、 Numpy庫簡介 1.1、概念 NumPy(Numerical Python)是一個開源的Python科學計算庫&#xff0c;旨在為Python提供 高性能的多維數組對象和一系列工具。NumPy數組是Python數據分析的基礎&#xff0c;許多 其他的數據處理庫&#xff08;如Pandas、SciPy&#xff09;都依賴于Num…

【SQL】MySQL中的字符串處理函數:concat 函數拼接字符串,COALESCE函數處理NULL字符串

MySQL中的字符串處理函數&#xff1a;concat 函數 一、concat &#xff08;&#xff09;函數 1.1、基本語法1.2、示例1.3、特殊用途 二、COALESCE&#xff08;&#xff09;函數 2.1、基本語法2.2、示例2.3、用途 三、進階練習 3.1 條件和 SQL 語句3.2、解釋 一、concat &…

windows下適用msvc編譯ffmpeg 適用于ffmpeg-7.1

需要的工具: visual studio 2019 (可以是其他版本&#xff0c;只是本人電腦上裝的為2019) msys2 ffmpeg-7.1源碼 1. 修改msys2_shell.cmd 在msys2目錄修改msys2_shell.cmd 打開后找到行set MSYS2_PATH_TYPEinherit 刪除開頭的rem 2. 運行msys2 運行x64 Native Tools Command …

2025年軟考報名費用是多少?全國費用匯總!

軟考報名時間終于確定了&#xff01;想要參加2025年軟考的同學們注意啦&#xff01;特別是那些一年只有一次考試機會的科目&#xff0c;千萬不要錯過哦&#xff01;這里為大家整理了各地的報名時間、科目、費用等信息&#xff0c;快來看看吧&#xff01; 一、2025年軟考時間安…

【LeetCode459】重復的子字符串

題目描述 給定一個非空的字符串 s &#xff0c;檢查是否可以通過由它的一個子串重復多次構成。 思路與算法 關鍵詞&#xff1a;利用字符串的重復性質&#xff1b;字符串的拼接技巧&#xff1b;逆推法假設原始字符串 s 是由某個子串 sub 重復多次構成的。也就是說&#xff0c…

JAVA面試常見題_基礎部分_Dubbo面試題(上)

Dubbo 支持哪些協議&#xff0c;每種協議的應用場景&#xff0c;優缺點&#xff1f; ? dubbo&#xff1a; 單一長連接和 NIO 異步通訊&#xff0c;適合大并發小數據量的服務調用&#xff0c;以及消費者遠大于提供者。傳輸協議 TCP&#xff0c;異步&#xff0c;Hessian 序列化…

掌握Git:從入門到精通的完整指南

Git是什么&#xff1f; Git是一個分布式版本控制系統&#xff0c;最初由Linus Torvalds在2005年為管理Linux內核開發而創建 它的主要功能是跟蹤文件的更改&#xff0c;協調多個開發者之間的工作&#xff0c;并幫助團隊高效地管理項目代碼。Git不僅適用于大型開源項目&#xf…

數據安全_筆記系列05:數據合規與隱私保護(GDPR、CCPA、中國《數據安全法》)深度解析

數據安全_筆記系列05&#xff1a;數據合規與隱私保護&#xff08;GDPR、CCPA、中國《數據安全法》&#xff09;深度解析 在全球數據跨境流動和隱私保護強監管的背景下&#xff0c;企業需同時滿足多法域合規要求。以下從 法規要點、核心差異、實施策略、跨境傳輸、典型案例 等維…