Linux kernel 的 kretprobe 機制和 kprobe 完全不同,本質原因在于,函數的入口地址是固定的,但函數的返回地址不固定,由于返回位置不固定,無法固定函數大小,無法事先插樁。一圖以示之:
想在函數返回時插入個 hook,只有在函數被調用時確定了函數返回地址(x86 為例,壓棧返回地址)后才可能。
因此,kprobe 在register 時即可將 hook 掛載,與 kprobe 不同,kretprobe 需在函數每次被調用時才能將 hook 掛載。這只是事情的輪廓,“在函數調用時掛載 hook” 才是大頭。
task 將函數返回地址替換成 kretprobe 的 hook 地址之前要保存舊返回地址,由于函數可被不同task 同時調用,因此不同 task 需擁有獨立的 kretprobe instance。
同一個 kretprobe hook,不同 kretprobe instance,Linux kernel 預分配了若干(與 CPU 數量相關) kretprobe instance,掛接在 kretprobe 的某 list 上,每當有 task 需要 kretprobe 特定函數時,在函數的入口處先從 kretprobe 的 list 上摘出一 kretprobe instance 供自己私用,此時函數返回地址已經壓棧,替換返地址為 hook 前將其 save 在獨享的 kretprobe instance 中。
很長一段時間跨越很多內核版本,多個 kretprobe instance 以 hlist node 的方式掛接在以 task地址 hash 為 key 的 hlist 上,而對 hlist node 的 CURD 必然涉及 lock,對于高頻調用的熱點函數,kretprobe 里的這個lock 相當于自設的路障hash 到同一個 bucket 的 task 同時調用一個函數時會被串行化,嚴重影響性能,甚至使系統 soft/hard lockup。這是一個知道的人很少的秘密。
為什么不用 percpu lock? 因為函數調用返回前可能發生 task 遷移
后來,那些煤炭奈兒(maintainer,妹忒訥兒估計也發現了問題,提交了一些派馳(patch),將hlist 改成了 CAS-based lock-free free list, 但人家自己也說了 Not the fastest thing in theworld under heavy contention, but simple and correct,詳見源文件
上面這些話,請自行比較不同內核版本的 pre handler kretprobe 函數實現。該函數的注釋是:This kprobe pre handler is registered with every kretprobe. When probe hits it will set upthe return probe.
so?
別張口就來,掛 kretprobe 的前提是你理解它的副作用,而不是只知道個詞,特別是那些上了ebpf 毒癮的。
我討厭一些脫離一線很久卻又要彰顯自己懂得很多而對工人精確指點的經理,這些經理只給出一祈使句指導,代碼腳本還是工人照著經理意思去寫,經理彰顯才華后,事了拂衣去。
經理知道 kretprobe 可以修改函數返回值,但他大概不知道 kretprobe 隱藏的秘密。知道這些秘密的經理不會指使工人用 kretprobe 修改返回值。經理就好好當經理,做好資源和人力的分配調度,別天天混進工人隊伍里瞎指揮,還美其名日技術導向,這就是扯淡。
kretprobe 的理論解法是將 return address 也固定,因此理論上可以截獲 ret 指令,進入一個common stub hook 中判定該函數是不是需要被 hook,如果不需要這就返回,如果需要就先調用 hook 再返回,但依然會引入別的開銷,那么可以縮小替換范圍,只在 kretprobe function 附近搜索并替換 ret 指令。
工人提出用 kretprobe 修改 init cwnd,經理會說這是非標的方案,kprobe/kretprobe 更多只做 debug 和可觀測性,不能上線...但工人想修改 nit cwnd 卻沒方案時,經理會讓工人用kretprobe 來改,絕口不提是否非標。經理知道 kprobe/kretprobe,但并不真懂,僅科普水平,或做過 demo,但也僅此。對技術細節非常感興趣又親自指揮細節的經理不是合格經理。但不知何時,不知為什么,工人們普遍覺得懂技術的經理才合格,于是經理們不得不去懂點技術,顯得很 geek,這樣才是真經理。很多經理都會此地無銀三百兩式地強調自己寫過代碼,懂技術,可也沒人問啊。
審核編輯:劉清
-
Linux系統
+關注
關注
4文章
595瀏覽量
27510 -
分配器
+關注
關注
0文章
195瀏覽量
25832 -
CAS
+關注
關注
0文章
35瀏覽量
15235 -
Hash算法
+關注
關注
0文章
43瀏覽量
7417
原文標題:kprobe 和 kretprobe 隱藏的秘密
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
說說android與linux有啥區別
你知道linux kernel內存回收機制是怎樣的?
![你知道<b class='flag-5'>linux</b> <b class='flag-5'>kernel</b>內存回收<b class='flag-5'>機制</b>是怎樣的?](https://file.elecfans.com/web1/M00/91/D0/pIYBAFzU8eqAKGCjAACdtz29bZA504.png)
評論