0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux kernel的kretprobe機(jī)制和kprobe有何區(qū)別?

Linux閱碼場 ? 來源:Linux閱碼場 ? 2023-08-07 09:15 ? 次閱讀

Linux kernel 的 kretprobe 機(jī)制和 kprobe 完全不同,本質(zhì)原因在于,函數(shù)的入口地址是固定的,但函數(shù)的返回地址不固定,由于返回位置不固定,無法固定函數(shù)大小,無法事先插樁。一圖以示之:

0b02694e-34bc-11ee-9e74-dac502259ad0.png

想在函數(shù)返回時插入個 hook,只有在函數(shù)被調(diào)用時確定了函數(shù)返回地址(x86 為例,壓棧返回地址)后才可能。

因此,kprobe 在register 時即可將 hook 掛載,與 kprobe 不同,kretprobe 需在函數(shù)每次被調(diào)用時才能將 hook 掛載。這只是事情的輪廓,“在函數(shù)調(diào)用時掛載 hook” 才是大頭。

task 將函數(shù)返回地址替換成 kretprobe 的 hook 地址之前要保存舊返回地址,由于函數(shù)可被不同task 同時調(diào)用,因此不同 task 需擁有獨立的 kretprobe instance。

同一個 kretprobe hook,不同 kretprobe instance,Linux kernel 預(yù)分配了若干(與 CPU 數(shù)量相關(guān)) kretprobe instance,掛接在 kretprobe 的某 list 上,每當(dāng)有 task 需要 kretprobe 特定函數(shù)時,在函數(shù)的入口處先從 kretprobe 的 list 上摘出一 kretprobe instance 供自己私用,此時函數(shù)返回地址已經(jīng)壓棧,替換返地址為 hook 前將其 save 在獨享的 kretprobe instance 中。

很長一段時間跨越很多內(nèi)核版本,多個 kretprobe instance 以 hlist node 的方式掛接在以 task地址 hash 為 key 的 hlist 上,而對 hlist node 的 CURD 必然涉及 lock,對于高頻調(diào)用的熱點函數(shù),kretprobe 里的這個lock 相當(dāng)于自設(shè)的路障hash 到同一個 bucket 的 task 同時調(diào)用一個函數(shù)時會被串行化,嚴(yán)重影響性能,甚至使系統(tǒng) soft/hard lockup。這是一個知道的人很少的秘密。

為什么不用 percpu lock? 因為函數(shù)調(diào)用返回前可能發(fā)生 task 遷移

后來,那些煤炭奈兒(maintainer,妹忒訥兒估計也發(fā)現(xiàn)了問題,提交了一些派馳(patch),將hlist 改成了 CAS-based lock-free free list, 但人家自己也說了 Not the fastest thing in theworld under heavy contention, but simple and correct,詳見源文件

上面這些話,請自行比較不同內(nèi)核版本的 pre handler kretprobe 函數(shù)實現(xiàn)。該函數(shù)的注釋是:This kprobe pre handler is registered with every kretprobe. When probe hits it will set upthe return probe.

so?

別張口就來,掛 kretprobe 的前提是你理解它的副作用,而不是只知道個詞,特別是那些上了ebpf 毒癮的。

我討厭一些脫離一線很久卻又要彰顯自己懂得很多而對工人精確指點的經(jīng)理,這些經(jīng)理只給出一祈使句指導(dǎo),代碼腳本還是工人照著經(jīng)理意思去寫,經(jīng)理彰顯才華后,事了拂衣去。

經(jīng)理知道 kretprobe 可以修改函數(shù)返回值,但他大概不知道 kretprobe 隱藏的秘密。知道這些秘密的經(jīng)理不會指使工人用 kretprobe 修改返回值。經(jīng)理就好好當(dāng)經(jīng)理,做好資源和人力的分配調(diào)度,別天天混進(jìn)工人隊伍里瞎指揮,還美其名日技術(shù)導(dǎo)向,這就是扯淡。

kretprobe 的理論解法是將 return address 也固定,因此理論上可以截獲 ret 指令,進(jìn)入一個common stub hook 中判定該函數(shù)是不是需要被 hook,如果不需要這就返回,如果需要就先調(diào)用 hook 再返回,但依然會引入別的開銷,那么可以縮小替換范圍,只在 kretprobe function 附近搜索并替換 ret 指令。

工人提出用 kretprobe 修改 init cwnd,經(jīng)理會說這是非標(biāo)的方案,kprobe/kretprobe 更多只做 debug 和可觀測性,不能上線...但工人想修改 nit cwnd 卻沒方案時,經(jīng)理會讓工人用kretprobe 來改,絕口不提是否非標(biāo)。經(jīng)理知道 kprobe/kretprobe,但并不真懂,僅科普水平,或做過 demo,但也僅此。對技術(shù)細(xì)節(jié)非常感興趣又親自指揮細(xì)節(jié)的經(jīng)理不是合格經(jīng)理。但不知何時,不知為什么,工人們普遍覺得懂技術(shù)的經(jīng)理才合格,于是經(jīng)理們不得不去懂點技術(shù),顯得很 geek,這樣才是真經(jīng)理。很多經(jīng)理都會此地?zé)o銀三百兩式地強調(diào)自己寫過代碼,懂技術(shù),可也沒人問啊。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    588

    瀏覽量

    27267
  • 分配器
    +關(guān)注

    關(guān)注

    0

    文章

    193

    瀏覽量

    25667
  • CAS
    CAS
    +關(guān)注

    關(guān)注

    0

    文章

    34

    瀏覽量

    15174
  • Hash算法
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    7378

原文標(biāo)題:kprobe 和 kretprobe 隱藏的秘密

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    說說android與linux區(qū)別

    就是靠著linux 才發(fā)展起來的,現(xiàn)在來說說區(qū)別吧。嵌入式android源碼架構(gòu):uboot+linux kernel+android(
    發(fā)表于 11-04 07:53

    STM32單片機(jī)與LINUX操作系統(tǒng)區(qū)別

    STM32與LINUX分別是什么?STM32與LINUX區(qū)別
    發(fā)表于 12-15 06:20

    Linuxkernel_timer教程

    Linuxkernel_timer教程,很好的Linux自學(xué)資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-15 17:59 ?12次下載

    DVR和NVR區(qū)別 誰將最終占領(lǐng)市場?

    DVR和NVR區(qū)別 誰將最終占領(lǐng)市場?
    發(fā)表于 12-27 22:19 ?0次下載

    Linux-kernel-3 0的移植記錄

    Linux-kernel-3 0的移植記錄
    發(fā)表于 10-31 11:33 ?7次下載
    <b class='flag-5'>Linux-kernel</b>-3 0的移植記錄

    你知道linux kernel內(nèi)存回收機(jī)制是怎樣的?

    無論計算機(jī)上有多少內(nèi)存都是不夠的,因而linux kernel需要回收一些很少使用的內(nèi)存頁面來保證系統(tǒng)持續(xù)內(nèi)存使用。頁面回收的方式頁回寫、頁交換和頁丟棄三種方式:如果一個很少使用的
    發(fā)表于 05-10 11:37 ?890次閱讀
    你知道<b class='flag-5'>linux</b> <b class='flag-5'>kernel</b>內(nèi)存回收<b class='flag-5'>機(jī)制</b>是怎樣的?

    Linux Kernel 5.2.2震撼發(fā)布!

    在首個維護(hù)版本更新之后,在kernel.org官網(wǎng)上已經(jīng)將Linux Kernel 5.2分支標(biāo)記為“Stable”,意味著已經(jīng)準(zhǔn)備好大規(guī)模部署了,所有GNU/Linux發(fā)行版本都應(yīng)該
    的頭像 發(fā)表于 08-09 17:01 ?2831次閱讀

    深入探究Linux中的Kprobe機(jī)制

    概述 kprobe機(jī)制用于在內(nèi)核中動態(tài)添加一些探測點,可以滿足一些調(diào)試需求。本文主要探尋kprobe的執(zhí)行路徑,也就是說如何trap到kprobe,以及如何回到原路徑繼續(xù)執(zhí)行。 實例
    的頭像 發(fā)表于 01-02 11:53 ?2503次閱讀

    Linux_Kernel_Developments內(nèi)核開發(fā)

    Linux_Kernel_Developments內(nèi)核開發(fā)詳細(xì)說明。
    發(fā)表于 04-07 14:27 ?37次下載
    <b class='flag-5'>Linux_Kernel</b>_Developments內(nèi)核開發(fā)

    ZigBee 與 Z-Wave:區(qū)別?

    ZigBee 與 Z-Wave:區(qū)別
    的頭像 發(fā)表于 01-03 09:45 ?1719次閱讀
    ZigBee 與 Z-Wave:<b class='flag-5'>有</b><b class='flag-5'>何</b><b class='flag-5'>區(qū)別</b>?

    接地基礎(chǔ)知識:PE 和 FG 區(qū)別?

    接地基礎(chǔ)知識:PE 和 FG 區(qū)別
    的頭像 發(fā)表于 03-10 15:07 ?1.3w次閱讀
    接地基礎(chǔ)知識:PE 和 FG <b class='flag-5'>有</b><b class='flag-5'>何</b><b class='flag-5'>區(qū)別</b>?

    淺談Linux kernel中的同步機(jī)制

    同步就是進(jìn)程與進(jìn)程之間,進(jìn)程與系統(tǒng)資源之間的交互。由于 Linux內(nèi)核采用的是多任務(wù),所以在多個進(jìn)程之間,必須要有同步機(jī)制來保證彼此協(xié)調(diào)。
    的頭像 發(fā)表于 05-04 17:06 ?818次閱讀

    likely與unlikely在Linux kernel區(qū)別

    likely() 與 unlikely() 在 Linux kernel 中隨處可見,那為什么要用它們?它們之間什么區(qū)別呢? 首先明確: if (likely(value)) 等價于
    的頭像 發(fā)表于 07-20 11:06 ?955次閱讀

    異構(gòu)集成 (HI) 與系統(tǒng)級芯片 (SoC) 區(qū)別?

    異構(gòu)集成 (HI) 與系統(tǒng)級芯片 (SoC) 區(qū)別
    的頭像 發(fā)表于 11-29 15:39 ?1691次閱讀
    異構(gòu)集成 (HI) 與系統(tǒng)級芯片 (SoC) <b class='flag-5'>有</b><b class='flag-5'>何</b><b class='flag-5'>區(qū)別</b>?

    光耦與光繼電器區(qū)別?

    光耦與光繼電器區(qū)別
    的頭像 發(fā)表于 12-13 13:59 ?783次閱讀
    光耦與光繼電器<b class='flag-5'>有</b><b class='flag-5'>何</b><b class='flag-5'>區(qū)別</b>?