国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

基于ebpf的性能工具-bpftrace腳本語法

Rice嵌入式開發(fā)技術分享 ? 來源:Rice 嵌入式開發(fā)技術分享 ? 作者:Rice 嵌入式開發(fā)技 ? 2023-09-04 16:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

bpftrace 通過高度抽象的封裝來使用 eBPF,大多數(shù)功能只需要寥寥幾筆就可以運行起來,可以很快讓我們搞清楚 eBPF 是什么樣的,而暫時不關心 eBPF 復雜的內(nèi)部機理。由于 bpftrace 深受 AWK 和 c 的影響,bpftrace 使用起來于 AWK 非常相似,那些內(nèi)核 hook 注入點幾乎可以按普通字符串匹配來理解,非常容易上手。

前面我們介紹了如何部署bpftrace工具,并且介紹了如何運行bpftrace腳本,這篇文章將介紹bpftrace腳本的語法。

基于ubuntu22.04-深入淺出 eBPF

基于ebpf的性能工具-bpftrace

bpftrace腳本語法

腳本格式

  • bpftrace腳本基本格式如下:
probe{
actions;
}
  • bpftrace語法深受AWK的影響,{前的部分相當于AWK的condition,{}中的部分相當于AWK的action。只不過bpftrace執(zhí)行actions的條件是觸發(fā)probe名稱指定的事件。
  • probe是探針的名稱,我們知道內(nèi)核中函數(shù)非常多,為了方便,內(nèi)核對probe做了namespace處理,這里的probe通常是以冒號:分割的一組名稱,比如:
tracepointtick_stop
kprobe:do_sys_open
  • 顯然,最后一部分表示的是函數(shù)名稱,其他部分則是namespace,這樣做有兩點好處:①便于查找函數(shù);②便于定位不同模塊中的同名函數(shù)。

  • bpftrace除了可以監(jiān)聽指定的probe事件,還有兩個特殊的probe:BEGIN,END。這與AWK類似,它們分別在bpftrace程序執(zhí)行開始、結(jié)束時,無條件的執(zhí)行一些操作,比如完成一些初始化、清理工作等。

BEGIN{
print("helloworld.n");
}

END{
print("byeworld.n");
}
  • filter是可選的,有時候我們只需要探測特定條件下函數(shù)的行為,比如參數(shù)為某個值的時候,就可以用到filter,這需要了解bpftrace如何訪問probe的變量,我們稍晚再說。

prbbe參數(shù)

ebpf支持的probe:hardware,iter,kfunc,kprobe,software,tracepoint,uprobe。

9c747342-4af9-11ee-bb52-92fbcf53809c.png
  1. dynamic tracing
  • ebpf提供了內(nèi)核和應用的動態(tài)trace,分別用于探測函數(shù)入口處和函數(shù)返回(ret)處的信息。

    • ①面向內(nèi)核的 kprobe/kretprobe,k = kernel
    • ②面向應用的 uprobe/uretprobe,u = user land
  • kprobe/kretprobe 可以探測內(nèi)核大部分函數(shù),出于安全考慮,有部分內(nèi)核函數(shù)不允許安裝探針,另外也可以配合 offset 探測函數(shù)中任意位置的信息。

  • uprobe/uretprobe 則可以為應用的任意函數(shù)安裝探針。

  • 動態(tài) trace 技術依賴內(nèi)核和應用的符號表,對于那些 inline 或者 static 函數(shù)則無法直接安裝探針,需要自行通過 offset 實現(xiàn)??梢越柚?nm 或者 strings 指令查看應用的符號表。

  • 這兩種動態(tài) trace 技術的原理與 GDB 類似,當對某段代碼安裝探針,內(nèi)核會將目標位置指令復制一份,并替換為 int3 中斷, 執(zhí)行流跳轉(zhuǎn)到用戶指定的探針 handler,再執(zhí)行備份的指令,如果此時也指定了 ret 探針,也會被執(zhí)行,最后再跳轉(zhuǎn)回原來的指令序列。

  • kprobe 和 uprobe 可以通過 arg0、arg1... ... 訪問所有參數(shù);kretprobe 和 uretprobe 通過 retval 訪問函數(shù)的返回值。除了基本類型:char、int 等,字符串需通過 str() 函數(shù)才能訪問。

  1. static tracing
  • 靜態(tài) trace,所謂 “靜態(tài)” 是指探針的位置、名稱都是在代碼中硬編碼的,編譯時就確定了。靜態(tài) trace 的實現(xiàn)原理類似 callback,當被激活時執(zhí)行,關閉時不執(zhí)行,性能比動態(tài) trace 高一些。

    • ① 內(nèi)核中的靜態(tài)trace:tracepoint
    • ② 應用中的靜態(tài)trace: usdt = Userland Statically Defined Tracing
  • 靜態(tài) trace 已經(jīng)在內(nèi)核和應用中飽含了探針參數(shù)信息,可以直接通過 args->參數(shù)名 訪問函數(shù)參數(shù)。tracepoint 的 參數(shù) format 信息可以通過 bpftrace -v probe 查看:

youyeetoo@youyeetoo:~$bpftrace-lvtracepointsys_exit
tracepointsys_exit
longid
longret
youyeetoo@youyeetoo:~$
  • 或者訪問debugfs:
youyeetoo@youyeetoo:~$cat/sys/kernel/debug/tracing/events/raw_syscalls/sys_exit/format
name:sys_exit
ID:348
format:
field:unsignedshortcommon_type;offset:0;size:2;signed:0;
field:unsignedcharcommon_flags;offset:2;size:1;signed:0;
field:unsignedcharcommon_preempt_count;offset:3;size:1;signed:0;
field:intcommon_pid;offset:4;size:4;signed:1;

field:longid;offset:8;size:8;signed:1;
field:longret;offset:16;size:8;signed:1;

printfmt:"NR%ld=%ld",REC->id,REC->ret
youyeetoo@youyeetoo:~$

內(nèi)置變量

無論 Dynamic tracing 或者 Static tracing,它們的目的都是監(jiān)聽特定函數(shù)調(diào)用事件,這些函數(shù)即可以在內(nèi)核中,也可以在用戶態(tài)的應用或者 lib 中。獲知這些函數(shù)調(diào)用時的參數(shù)、返回值就已經(jīng)實現(xiàn)了開發(fā)者大半目標。除此之外,bpfstrace 還內(nèi)置了一些變量,用戶訪獲得探測對象自身信息。這些變量在 bpftrace 中直接訪問即可,如下:

  • pid / tid:Bpftrace或者說eBPF工作在內(nèi)核,因此這些變量都與內(nèi)核中進程表示有關。先說tid,內(nèi)核中線程與進程沒做作明確區(qū)分,它們都是相同的調(diào)度對象task_sruct。tid是thread id的縮寫,由于歷史原因,在task中的成員是task_sruct.pid。所以對于Linux內(nèi)核,線程=輕量級進程。而pid實際上指的是內(nèi)核中進程組,由task中的task_sruct.tgid成員表示。也就是說,進程=線程組。
  • uid / gid:執(zhí)行函數(shù)的用戶ID、組ID。
  • nsecs:時間戳,納秒。
  • elapsed:ebpfs 啟動后的納秒數(shù)。
  • numaid:NUMA = Non-Uniform Memory Access,與多核 CPU 的內(nèi)存訪問相關。
  • cpu:當前 cpu 編號,從 0 開始。
  • comm:進程名稱,通常為進程可執(zhí)行文件名。
  • kstack:內(nèi)核棧。
  • ustack: 用戶棧。
  • arg0, arg1, ..., argN:函數(shù)參數(shù)。
  • sarg0, sarg1, ..., sargN:函數(shù)參數(shù)(棧中)。
  • retval:返回值。
  • func:函數(shù)名,可以在可執(zhí)行文件的符號表中這個函數(shù)名。
  • probe:探針的完整名稱,也就是 bpftrace 中 形如 'kprobe:do_nanosleep'
  • curtask:當前 task struct。
  • rand:一個無符號 32 位隨機數(shù)。
  • cgroup:當前進程的 Cgroup,內(nèi)核資源組,類似 namespace,docker 等虛擬化技術即基于內(nèi)核提供的這一基礎設施。
  • cpid:子進程 pid,bpftrace 允許通過 -c 指定一個 cmd 運行,然后在該進程上安裝 probe。
  • 2, ..., #:bpftrace 程序自身的位置參數(shù)

全局變量

  • 全局變量@name,所謂的全局變量:①對所有的probe actions可見,②bpftrace生命周期內(nèi)可見。

  • bpftrace支持兩種變量形式:

    • ① 簡單變量,@name = value;簡單變量就是單純的變量名和值,很容易理解,你可以在腳本中創(chuàng)建任意數(shù)量的簡單變量。
    • ② Map,@name[key] = value;Map非常接近Python中的Dict,或者C中的數(shù)組,但數(shù)組索引可以是數(shù)字、字符串等。例如借助內(nèi)置變量tid可以為每個線程記錄獨立的數(shù)值。
  • 測試例子:

kprobe:do_nanosleep{
@start[tid]=nsecs;
}

kretprobe:do_nanosleep/@start[tid]!=0/{
printf("sleptfor%dmsn",(nsecs-@start[tid])/1000000);
delete(@start[tid]);
}
  • 運行效果:
youyeetoo@youyeetoo:~$bpftracebpf_test.bt
Attaching2probes...
sleptfor0ms
sleptfor0ms
sleptfor0ms
sleptfor0ms
sleptfor0ms
sleptfor0ms
sleptfor0ms

臨時變量

$name, 只在當前action中有效,超出action的{}不具備記憶能力。

內(nèi)置函數(shù)

bpftrace無法自定義函數(shù),但提供了約36個內(nèi)置函數(shù),可以在bpftrace腳本的任意位置調(diào)用它們。完整的列表可以參考官方文檔:(https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md)。

bpftrace的函數(shù)非常有限,原因是bpftrace腳本會編譯為bytecode,交由內(nèi)核中的eBPF VM執(zhí)行,出于安全和效率考慮,eBPF VM不能允許用戶執(zhí)行任意函數(shù),僅允許執(zhí)行限定的函數(shù),或缺有限的數(shù)據(jù)。

  1. printf -- printf(fmt, ...)bpftrace的printf函數(shù)行為與C語言基本一致,區(qū)別在于它只支持有限的格式化字符,不如C語言支持的那么多。
BEGIN{
print("helloworld.n");
}

END{
print("byeworld.n");
}
  1. time -- time(fmt)time函數(shù)用于打印當前時間,可以通過參數(shù)中的格式化字符串指定,如果沒有指定格式化字符串,那么默認格式是%H:%M:%Sn。time函數(shù)完全兼容strftime的格式化字符,下面列出一些常用項:
  • %S 秒,00-60;
  • %M 分鐘,00-59;
  • %I 小時,01-12;%H 小時,00-23;
  • %d 每月的第幾天,01-31;
  • %w 星期,0-6, 0 指 星期日;
  • %m 月份,01-12;
  • %y 年份,00-99;%Y 完整的年份;

「注意:格式化字符結(jié)尾不要忘記換行,否則不會自動清空緩沖區(qū)到標準輸出,就看不到輸出了。」

youyeetoo@youyeetoo:~$bpftrace-e'interval1{time("%Y%H:%M:%Sn");}'
Attaching1probe...
202316:35:30
202316:35:31
202316:35:32
^C
  1. system該函數(shù)可以調(diào)用 shell,用于 probe 觸發(fā)其他用戶態(tài)可執(zhí)行程序非常有用。下面是一個簡單的例子,定時調(diào)用 `ps. 查看當前進程:
youyeetoo@youyeetoo:~$bpftrace--unsafe-e'kprobe:do_nanosleep{system("ps-p%dn",pid);}'
Attaching1probe...
PIDTTYTIMECMD
933?00:00:00cron
^C
  1. ustack當使用 uprobe 時,很可能需要關注用戶進程的 stack 情況,ustack 函數(shù)接受 2 個參數(shù),這兩個參數(shù)可以同時使用,或者只用 1 個。
  • mode,stack 模式,可選 bpftrace、perf;
  • limit,一個整數(shù),獲取 stack 的最大深度;
youyeetoo@youyeetoo:~$bpftrace-e'uprobereadline{printf("%sn",ustack(perf,3));}'
stdin:1:1-21:WARNING:attachingtouprobetargetfile'/usr/bin/bash'butmatched2binaries
uprobereadline{printf("%sn",ustack(perf,3));}
~~~~~~~~~~~~~~~~~~~~
Attaching1probe...

56440bb42690readline+0(/usr/bin/bash)
56440bb42690readline+0(/usr/bin/bash)
56440bb42690readline+0(/usr/bin/bash)

控制語句

bpftrace 也提供了常見的流程控制語句:① 條件語句 ② 循環(huán)語句

  1. 條件語句
  • bpftrace的條件語句用法與C語言完全一樣:
if(condition){
statements;//A
}else{
statements;//B
}
  • 當滿足條件時執(zhí)行 A 處語句,否則執(zhí)行 B 處語句。當然也可能有以下更簡單的形式,沒有 else 部分,條件滿足時執(zhí)行 A 處語句,然后執(zhí)行 B 處語句,否則跳過 A 處語句:
if(condition){
statements;//A
}

statements;//B
  • 多個 if-else 也可能連接在一起:
if(condition){
statements;//A
}elseif(condition){
statements;//B
}elseif(condition){
statements;//C
}else{
statements;//D
}
  • 測試樣例:
BEGIN{
$num=$1;
if($num>=10){
$result="A";
}elseif($num>=5){
$result="B";
}else{
$result="C"
}
printf("result:%sn",$result);
exit();
}
  • 測試樣例結(jié)果:
youyeetoo@youyeetoo:~$bpftracebpf_test.bt15
Attaching1probe...
result:A

youyeetoo@youyeetoo:~$bpftracebpf_test.bt8
Attaching1probe...
result:B

youyeetoo@youyeetoo:~$bpftracebpf_test.bt3
Attaching1probe...
result:C

youyeetoo@youyeetoo:~$
  1. 循環(huán)語句
while(condition){
//dosomething
}
  • 測試樣例:
BEGIN{
$i=0;
while($i10){
printf("i=%dn",$i);
$i++
}
exit();
}

  • 測試樣例結(jié)果:
youyeetoo@youyeetoo:~$bpftracebpf_test.bt
Attaching1probe...
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9

審核編輯 黃宇


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

    關注

    5198

    文章

    20442

    瀏覽量

    333986
  • 函數(shù)
    +關注

    關注

    3

    文章

    4417

    瀏覽量

    67501
  • 語法
    +關注

    關注

    0

    文章

    45

    瀏覽量

    10644
  • 腳本
    +關注

    關注

    1

    文章

    409

    瀏覽量

    29192
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    解構(gòu)內(nèi)核源碼eBPF樣例編譯過程

    了解和掌握純c語言的ebpf編譯和使用,有助于我們加深對于eBPF技術原理的進一步掌握,也有助于開發(fā)符合自己業(yè)務需求的高性能ebpf程序。
    的頭像 發(fā)表于 04-17 14:05 ?2386次閱讀

    Linux跟蹤工具bpftrace的原理和使用

    這篇文章介紹一個基于ebpf技術的強大工具--bpftrace。
    發(fā)表于 09-01 15:10 ?3336次閱讀
    Linux跟蹤<b class='flag-5'>工具</b><b class='flag-5'>bpftrace</b>的原理和使用

    如何在 Shell 腳本中執(zhí)行語法檢查調(diào)試模式

    LCTT 原創(chuàng)編譯,Linux中國 榮譽推出我們開啟了 Shell 腳本調(diào)試系列文章,先是解釋了不同的調(diào)試選項,下面介紹如何啟用 Shell 調(diào)試模式。寫完腳本后,建議在運行腳本之前先檢查
    發(fā)表于 12-31 11:04

    總結(jié)linux腳本語法和正則表達式的應用

    每日學一點之linux腳本語法以及正則表達式基礎
    發(fā)表于 11-08 09:23

    Makefile腳本語法簡介

    宏定義LEDS_CTL 的使用Makefile腳本語法簡介Makefile測試
    發(fā)表于 12-22 06:39

    openEuler 倡議建立 eBPF 軟件發(fā)布標準

    eBPF 被廣泛應用在云原生、可觀測、性能調(diào)優(yōu)、安全、硬件加速等領域,并且其應用場景還在快速擴展,各種場景基于 eBPF 技術的創(chuàng)新 idea 呈現(xiàn)井噴現(xiàn)象,eBPF 的時代已經(jīng)來臨
    發(fā)表于 12-23 16:21

    服務器端腳本與動態(tài)網(wǎng)頁設計,下載

    服務器端腳本與動態(tài)網(wǎng)頁設計 1. 了解服務器端腳本和動態(tài)網(wǎng)頁的有關概念 ; 2. 了解ASP、PHP的基本語法和基本功能 ; 3. 熟練掌握JSP的基本語法和基本
    發(fā)表于 04-28 16:44 ?0次下載

    強勁的Linux Trace工具 bpftrace for Linux 2018

    本文主要是Brendan Gregg在介紹 bpftrace在2018年的開發(fā)進展,以及對bpftrace的介紹和對Dtrace的區(qū)別介紹。
    的頭像 發(fā)表于 06-04 15:44 ?1.3w次閱讀
    強勁的Linux Trace<b class='flag-5'>工具</b> <b class='flag-5'>bpftrace</b> for Linux 2018

    eBPF是什么以及eBPF能干什么

    一、eBPF是什么 eBPF是extended BPF的縮寫,而BPF是Berkeley Packet Filter的縮寫。對linux網(wǎng)絡比較熟悉的伙伴對BPF應該比較了解,它通過特定的語法
    的頭像 發(fā)表于 07-05 15:17 ?1.3w次閱讀
    <b class='flag-5'>eBPF</b>是什么以及<b class='flag-5'>eBPF</b>能干什么

    基于ebpf性能工具-bpftrace

    運行情況對于診斷問題、優(yōu)化性能以及進行安全監(jiān)控至關重要。bpftrace作為一款強大的跟蹤工具,為開發(fā)人員和系統(tǒng)管理員提供了一種獨特的方式來監(jiān)視和分析Linux系統(tǒng)的內(nèi)部運行。本文描述bpft
    的頭像 發(fā)表于 09-04 16:02 ?1653次閱讀
    基于<b class='flag-5'>ebpf</b>的<b class='flag-5'>性能</b><b class='flag-5'>工具</b>-<b class='flag-5'>bpftrace</b>

    ebpf的快速開發(fā)工具--libbpf-bootstrap

    基于ubuntu22.04-深入淺出 eBPF 基于ebpf性能工具-bpftrace 基于ebpf
    的頭像 發(fā)表于 09-25 09:04 ?2370次閱讀
    <b class='flag-5'>ebpf</b>的快速開發(fā)<b class='flag-5'>工具</b>--libbpf-bootstrap

    基于ebpf性能工具應用

    曾利用Valgrind工具成功地發(fā)現(xiàn)并解決了一個隱藏在軟件中的bug,這充分體現(xiàn)了工具在開發(fā)過程中的重要性。 然而,同樣強大的bpftrace工具同樣具備簡潔而直觀的特點,能夠協(xié)助我們
    的頭像 發(fā)表于 11-08 16:19 ?1319次閱讀
    基于<b class='flag-5'>ebpf</b>的<b class='flag-5'>性能</b><b class='flag-5'>工具</b>應用

    腳本錯誤scripterror怎么解決

    腳本錯誤”(Script Error)通常是在運行或嘗試運行一段腳本或程序時出現(xiàn)的錯誤。這種錯誤可能源于許多不同的原因,包括語法錯誤、運行環(huán)境問題、依賴庫缺失等。解決腳本錯誤需要針對
    的頭像 發(fā)表于 11-26 14:46 ?1.5w次閱讀

    腳本調(diào)試工具有哪些?腳本調(diào)試工具怎么用?

    腳本調(diào)試是軟件開發(fā)過程中非常重要的一環(huán),它能幫助開發(fā)者快速定位并解決代碼中的錯誤。大多數(shù)編程語言都提供了各種各樣的腳本調(diào)試工具,本文將介紹一些常見的腳本調(diào)試
    的頭像 發(fā)表于 12-01 14:40 ?2109次閱讀

    Shell腳本檢查工具ShellCheck介紹

    ShellCheck是一個用于bash/sh shell腳本的靜態(tài)分析工具,可以輔助檢查腳本語法錯誤,給出建議增強腳本健壯性。
    的頭像 發(fā)表于 12-27 13:43 ?3487次閱讀
    Shell<b class='flag-5'>腳本</b>檢查<b class='flag-5'>工具</b>ShellCheck介紹