精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

基于ebpf的性能工具應用

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-08 16:19 ? 次閱讀

在實際的軟件開發過程中,內存問題常常是耗費大量時間進行分析的挑戰之一。為了更有效地定位和解決與內存相關的難題,一系列輔助工具應運而生,其中備受贊譽的Valgrind工具便是其中之一。事實上,筆者本人曾利用Valgrind工具成功地發現并解決了一個隱藏在軟件中的bug,這充分體現了工具在開發過程中的重要性。

然而,同樣強大的bpftrace工具同樣具備簡潔而直觀的特點,能夠協助我們高效地追蹤內存泄漏問題。在這方面,bpftrace提供了一種更加精細的、實時的分析方式,幫助開發人員準確地定位代碼中可能存在的內存泄漏情況。

構建樣例

我們編寫一個程序--mem_check.c,代碼中包含正確的申請內存和釋放內存的邏輯,同時包含存在內存泄露的代碼代碼。。

#include
#include

int main(){
char *p1 = NULL;
char *p2 = NULL;

for(int i = 0; i < 5; i++)
{
p1 = malloc(16);
}

for(int i = 0; i < 5; i++)
{
p2 = malloc(32);
free(p2);
}
getchar();
return 0;
}

上面的代碼非常簡單,我們申請了5次16個字節的內存,沒有釋放,存在內存泄露。申請5次32個字節的內存,有釋放,沒存在內存泄露。那么我們如何通過bpftrace定位呢?

我們通過bpftrace對mem_check.c進行動態的統計內存的申請和釋放,定位內存泄露的問題。我們需要對關鍵的兩個接口進行probe--malloc和free,這兩個接口的實現在libc中。

編譯mem_check.c文件,生成可執行文件:

gcc mem_check.c -o mem_check

探測mem_ckeck可執行文件

bpftrace可以對內核態進行探測也可以對用戶態進行探測,其中探針如下:

  • 內核態探針:kprobe/kretprobe
  • 用戶態探針:uprobe/uretprobe

mem_check.c是一個應用程序,顯然我們需要使用用戶態探針:uprobe/uretprobe

通過uprobe探測mem_check.c中的malloc函數,我們單行指令驗證,參數格式是 uprobe:可執行文件:函數名:

圖片

理論是沒有沒有問題,但實際發生錯誤:No probes to attach。原因:可執行文件mem_check中找不到符號:malloc,我們可以通過nm命令確定一下:

圖片

我們發現malloc是一個鏈接自GLIBC_2.2.5的符號,并不是mem_ckeck自身的符號,所以我們探測的符號修改libc庫中malloc符號,系統中可能存在多個c庫,我們需要找到mem_ckeck程序使用的C庫,通過ldd命令查看:

圖片

mem_check可執行文件使用的C庫為:/lib/x86_64-linux-gnu/libc.so.6,我們將可以執行文件替換為/lib/x86_64-linux-gnu/libc.so.6。再次執行,會出現大量內容,顯然是其他進程調用了malloc引起的,而我們的mem_ckeck還沒有運行,顯然還沒有探測我們的可執行程序。

bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc {printf("malloc calln")}'

我們需要進行過濾,增加filter只保留我們關心的應用程序的調用探測。bpftrace提供了系統變量comm表示可執行文件名 (進程名),只需要在上述指令中增加 filter,只處理comm=="mem_check"的malloc調用事件。左邊終端執行探測,右邊終端執行可執行文件。每調用一次malloc函數,就能探測到一次:

圖片

使用bpftrace腳本進一步探測

將上面的單行命令變為bpftrace腳本--bpf_test.bt

BEGIN {
printf("start proben");
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("malloc calln");
}

END {
printf("end proben");
}

探測mem_check中malloc的內存空間大小。

malloc的原型:

void *malloc(size_t size);

bpftrace的uprobe和kprobe可以通過內置變量arg0、arg1 ··· ··· 訪問函數參數,對bpf_test.bt修改就可以打印malloc申請內存的大小:

BEGIN {
printf("start proben");
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("malloc size: %dn", arg0);
}

END {
printf("end proben");
}

如下圖可以看到mem_check中申請內存的情況,最后一個malloc size 1024是mem_check自動創建輸出緩沖區申請的內存,不用理會。

圖片

探測mem_check中malloc的返回值

malloc的返回值是地址,需借助uretprobe進行探測,函數返回值可通過內置變量retval訪問。uretprobe的filter與malloc參數探測時類似,腳本修改為:

BEGIN {
printf("start proben");
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("malloc size: %dn", arg0);
}

uretprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("addr = %pn", retval);
}

END {
printf("end proben");
}

運行結果:

圖片

探測mem_check中free

我們已經探測到mem_check的malloc的內存大小,內存的地址,我們通過探測free,然后匹配malloc和free的情況就可以查找內存的泄漏點。腳本修改為:

BEGIN {
printf("start proben");
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("malloc size: %dn", arg0);
}

uretprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("addr = %pn", retval);
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:free /comm == "mem_check"/{
printf("free addr = %pn", arg0);
}

END {
printf("end proben");
}

運行結果:

圖片

探測內存泄露

上面我們已經探測到了mem_check中的malloc,free情況。我們可以通過malloc和free的地址集合差,就可以得到內存泄露的地址位置。

bpftrace底層使用的是eBPF的map作為存儲結構,可以簡單的看作K-V存儲,我們可以利用map來統計地址集合差,步驟如下:

  1. 定義一個map變量@mem:保存malloc返回的內存地址。
  2. 當探測到free調用時,將@mem對應地址刪除。
  3. 最后@mem剩下的就是內存泄露的地址。

內存泄露檢測腳本如下:

BEGIN {
printf("start proben");
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("malloc size: %dn", arg0);
@size = arg0;
}

uretprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /comm == "mem_check"/{
printf("addr = %pn", retval);
@mem[retval] = @size;

}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:free /comm == "mem_check"/{
printf("free addr = %pn", arg0);
delete(@mem[arg0]);
}

END {
printf("end proben");
}

運行結果:

圖片

如上圖,紅色框中就是沒有釋放的內存和內存大小。

總結

通過編寫一些簡單的bpftrace腳本,我們就可以監視應用程序的內存分配和釋放事件,捕獲內存泄漏的跡象。這種直接的實時監控方式,使得開發者能夠在問題出現時即刻獲得反饋,從而更加迅速地解決潛在的內存問題,提升軟件的穩定性和性能。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3002

    瀏覽量

    73887
  • 代碼
    +關注

    關注

    30

    文章

    4751

    瀏覽量

    68357
  • Valgrind
    +關注

    關注

    0

    文章

    9

    瀏覽量

    6797
收藏 人收藏

    評論

    相關推薦

    解構內核源碼eBPF樣例編譯過程

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

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

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

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

    ,并且介紹了如何運行bpftrace腳本,這篇文章將介紹bpftrace腳本的語法。 基于ubuntu22.04-深入淺出 eBPF 基于ebpf性能工具
    的頭像 發表于 09-04 16:04 ?957次閱讀
    基于<b class='flag-5'>ebpf</b>的<b class='flag-5'>性能</b><b class='flag-5'>工具</b>-bpftrace腳本語法

    關于 eBPF 安全可觀測性,你需要知道的那些事兒

    非常復雜的話題,牽一發而動全身,防御機制、加固配置、漏洞利用等等挑戰性的技術。在進行加固防御的過程中,又會產生性能或者系統穩定性相關的影響。從 eBPF + LSM 的角度可以更加可視化、數據豐富的觀測內核
    發表于 09-08 15:31

    openEuler 倡議建立 eBPF 軟件發布標準

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

    eBPF是什么以及eBPF能干什么

    規則使用基于寄存器的虛擬機來描述包過濾的行為。比較常用的功能是通過過濾來統計流量,tcpdump工具就是基于BPF實現的。而eBPF對它進行了擴展來實現更多的功能。 主要區別如下: 1)允許使用C 語言編寫
    的頭像 發表于 07-05 15:17 ?1.2w次閱讀
    <b class='flag-5'>eBPF</b>是什么以及<b class='flag-5'>eBPF</b>能干什么

    eBPF深入理解和實現原理

    簡單來說,wBPF 是一個在硬件上直接執行 eBPF 程序的系統。
    的頭像 發表于 06-14 09:25 ?3528次閱讀

    介紹eBPF針對可觀測場景的應用

    隨著eBPF推出,由于具有高性能、高擴展、安全性等優勢,目前已經在網絡、安全、可觀察等領域廣泛應用,同時也誕生了許多優秀的開源項目,如Cilium、Pixie等,而iLogtail 作為阿里內外千萬實例可觀測數據的采集器,eBPF
    的頭像 發表于 08-11 09:10 ?1540次閱讀

    openEuler倡議建立eBPF軟件發布標準

    eBPF 是一個能夠在內核運行沙箱程序的技術,提供了一種在內核事件和用戶程序事件發生時安全注入代碼的機制,使得非內核開發人員也可以對內核進行控制。隨著內核的發展,eBPF 逐步從最初的數據包過濾
    的頭像 發表于 12-06 10:29 ?542次閱讀

    Linux 內核:eBPF優勢和eBPF潛力總結

    Express Data Path (XDP):網絡驅動程序是最早可以附加 XDP BPF 鉤子的點。當收到一個數據包時,eBPF 程序就會被觸發運行。
    發表于 01-10 11:37 ?3055次閱讀

    什么是eBPFeBPF為何備受追捧?

    用云杉網絡 VP 向陽的話來說:“ eBPF 最重要(沒有之一)的特點是安全性” 。他表示,以往必須編寫內核模塊才能做到的工作現在基本都能做到。
    的頭像 發表于 05-06 11:41 ?2216次閱讀

    eBPF的前世今生?eBPF在使用中遇到的問題有哪些?

    在介紹eBPF (Extended Berkeley Packet Filter)之前,我們先來了解一下它的前身-BPF (Berkeley Packet Filter)伯克利數據包過濾器。
    的頭像 發表于 08-12 15:10 ?1569次閱讀
    <b class='flag-5'>eBPF</b>的前世今生?<b class='flag-5'>eBPF</b>在使用中遇到的問題有哪些?

    基于ebpf性能工具-bpftrace

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

    ebpf的快速開發工具--libbpf-bootstrap

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

    eBPF動手實踐系列三:基于原生libbpf庫的eBPF編程改進方案簡析

    在上一篇文章《eBPF動手實踐系列二:構建基于純C語言的eBPF項目》中,我們初步實現了脫離內核源碼進行純C語言eBPF項目的構建。libbpf庫在早期和內核源碼結合的比較緊密,如今的libbpf庫更加成熟,已經完全脫離內核源碼
    的頭像 發表于 03-19 14:19 ?767次閱讀
    <b class='flag-5'>eBPF</b>動手實踐系列三:基于原生libbpf庫的<b class='flag-5'>eBPF</b>編程改進方案簡析