国产电影一区二区三区,,欧美大片免费观看,伊人久久大香线蕉av,国产日韩成人内射视频

分享一個嵌入式開發調試利器!

Sanitizer簡介

Sanitizer是由Google發起的開源工具集,用于檢測內存泄露等(deng)問題。

鏈接://github.com/google/sanitizers/wiki/

它包(bao)括(kuo)了(le)AddressSanitizer、MemorySanitizer、ThreadSanitizer、LeakSanitizer等多(duo)種工具(ju)。這(zhe)些工具(ju)最初是(shi)LLVM項目的(de)一部分,后(hou)來也被GNU的(de)GCC編譯器支持(chi)。從GCC的(de)4.8版本(ben)開始(shi),就已經支持(chi)AddressSanitizer和ThreadSanitizer,而4.9版本(ben)則開始(shi)支持(chi)LeakSanitizer。

Sanitizer使用(yong)

1、AddressSanitizer的使用例(li)子

AddressSanitizer(ASan) 是一個快速(su)內存檢測(ce)器,可以檢測(ce)出(chu)緩沖區溢出(chu)、使用(yong)已釋放(fang)內存等問(wen)題。編(bian)譯時帶(dai)上參數(shu) -fsanitize=address及-g。

(1)捕捉棧緩(huan)沖區(qu)溢出(chu)問(wen)題:

AddressSanitizer.c:

// 微信公眾號:嵌入式大雜燴
#include

voidtest_func(void)
{
    int a[6] = {0};
    int b = a[6];    // 棧緩沖區溢出
}                     

intmain(int argc, char **argv)
{
 test_func();

return0;
}

編譯、運行:

gcc AddressSanitizer.c -fsanitize=address -g -o AddressSanitizer

執行結果分析:

觸發(fa)了檢測錯誤級別,終止程序并給出了程序運行異常的原因及異常的代碼位置。

(2)捕捉使(shi)用已釋放(fang)內存問題:

ThreadSanitizer.c:

// 微信公眾號:嵌入式大雜燴
#include

voidtest_func(void)
{
    char *p = malloc(10);
    p[0] = 1;
    free(p);
    p[0] = 1;  // 使用已釋放內存
}                     

intmain(int argc, char **argv)
{
 test_func();

return0;
}

2、ThreadSanitizer的使用例(li)子

ThreadSanitizer(TSan) 是一(yi)個(ge)數據(ju)競爭檢測器,可(ke)以用來分析線(xian)程競態(tai)、死鎖等線(xian)程相關問題。編(bian)譯時(shi)帶上參數 -fsanitize=thread及(ji)-g。

捕捉 線程間數(shu)據競爭(zheng) 問題:

// 微信公眾號:嵌入式大雜燴
#include
#include

int g_counter = 0;  // thread1、thread2競爭的數據

void *increment(void *arg)
{
    g_counter++;
}

void *decrement(void *arg)
{
    g_counter--;
}

voidtest_func(void)
{
    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, increment, NULL);
    pthread_create(&thread2, NULL, decrement, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("Counter value: %d\n", g_counter);
}

intmain(int argc, char **argv)
{
    test_func();

    return0;
}

編(bian)譯、運行:

gcc ThreadSanitizer.c -fsanitize=thread -g -pthread -o ThreadSanitizer

執行結果分析:

觸(chu)發了檢測警告級別(bie),程序(xu)仍能運行,并給出了程序(xu)運行有風(feng)險(xian)的(de)原因及(ji)有風(feng)險(xian)的(de)代(dai)碼位置(zhi)。

3、程序中(zhong)同(tong)時存(cun)在多處(chu)風(feng)險?

上面的(de)例子分別(bie)使(shi)用(yong)AddressSanitizer檢(jian)測(ce)(ce)器與(yu)ThreadSanitizer檢(jian)測(ce)(ce)器來檢(jian)測(ce)(ce)對應的(de)異常,可以較為精準(zhun)地檢(jian)測(ce)(ce)到對應的(de)異常。

如果程序中(zhong)同時存在多處風險呢(ni)?

這也是比較貼近我(wo)(wo)們(men)(men)的(de)實際(ji)應(ying)用的(de),畢竟我(wo)(wo)們(men)(men)并不知(zhi)道(dao)我(wo)(wo)們(men)(men)的(de)代碼里有哪(na)些可能(neng)存在的(de)風險。這種情(qing)況(kuang)我(wo)(wo)們(men)(men)要(yao)怎么檢測?

編譯(yi)時能同時帶上多(duo)個-fsanitize參數調用多(duo)個檢(jian)測器嗎?

可以(yi)同(tong)時帶,但有些檢測器(qi)不能同(tong)時使(shi)用。

AddressSanitizer與ThreadSanitizer檢測器不(bu)能同時使用。

但是,假如我們的程序中(zhong)恰好存在(zai)address異常(chang)(chang)與thread異常(chang)(chang)呢(ni),單獨使用AddressSanitizer檢測器(qi)、ThreadSanitizer檢測器(qi)的表現是怎樣的?

比如(ru),我們把上(shang)面(mian)3個例子的代碼(ma)放在一起:

test.c:

// 微信公眾號:嵌入式大雜燴
#include
#include
#include

int g_counter = 0;  // thread1、thread2競爭的數據

void *increment(void *arg)
{
    g_counter++;
}

void *decrement(void *arg)
{
    g_counter--;
}

// 測試:資源競爭
voidtest_func(void)
{
    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, increment, NULL);
    pthread_create(&thread2, NULL, decrement, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("Counter value: %d\n", g_counter);
}

// 測試:使用已釋放內存
voidtest_func1(void)
{
    char *p = malloc(10);

    printf("This is test_func1\n");

    p[0] = 1;
    free(p);
    p[0] = 1;  // 使用已釋放內存
}     

// 測試:棧緩沖區溢出
voidtest_func2(void)
{
    int a[6] = {0};
    int b = a[6];    // 棧緩沖區溢出
}     

intmain(int argc, char **argv)
{
    test_func();
    test_func1();
 test_func2();

    return0;
}

帶-fsanitize=thread參數編譯(yi)、運行:

執行結果分析:

ThreadSanitizer檢測器(qi)能正常檢測出資(zi)源競爭的問題,也檢測出了(le)test_func1中(zhong)的使用(yong)已釋放的(de)堆(dui)內存的問題并以(yi)警(jing)告級別(bie)報告,但沒有檢測(ce)出test_func2的棧(zhan)緩沖區溢出問題。

是不是因為test_func2運行在test_func1后(hou)面了,所(suo)以test_func2的(de)異常沒有被ThreadSanitizer檢測(ce)器檢測(ce)出來?

我們調換(huan)個位置看(kan)看(kan):

intmain(int argc, char **argv)
{
    test_func();
 test_func2();
    test_func1();

    return0;
}

顯然(ran),執行結果還(huan)是(shi)一樣的,test_func2的棧緩(huan)沖區溢出問題還是沒有被ThreadSanitizer檢測(ce)器檢測(ce)出來(lai)。

所以,大致得(de)出結論:當(dang)程序(xu)里存在thread異常(chang)與address異常(chang)時,使(shi)用ThreadSanitizer檢(jian)測器(qi)能準確檢(jian)測到thread異常(chang),能檢(jian)測到部(bu)分address異常(chang)。

帶-fsanitize=address參數編譯、運行:

執(zhi)行順序(xu):

intmain(int argc, char **argv)
{
    test_func();
    test_func1();
    test_func2();

    return0;
}

執行結(jie)果分析:

AddressSanitizer檢(jian)(jian)測器檢(jian)(jian)測到了test_func1中的已使用釋放的堆(dui)內存(cun)的(de)異常(chang)并(bing)(bing)以(yi)錯誤級別(bie)報告,并(bing)(bing)終止了(le)程序(xu);沒(mei)有(you)檢測到(dao)(dao)test_func的(de)資源競爭的(de)風險(xian);也(ye)沒(mei)有(you)檢測到(dao)(dao)test_func2的(de)棧緩沖區溢出的(de)問題,因為執行(xing)到(dao)(dao)test_func1的(de)時候程序(xu)已經被終止了(le),如果(guo)把test_func2放在test_func1之(zhi)前運行(xing),就能(neng)檢測到(dao)(dao)test_func2的(de)異常(chang)。

結(jie)論:當程(cheng)序里(li)存在thread異常(chang)與address異常(chang)時,使用AddressSanitizer檢測(ce)器能(neng)準(zhun)確檢測(ce)到第(di)一個觸發(fa)的address異常(chang),不能(neng)檢測(ce)到thread異常(chang)。

如果程(cheng)序中存(cun)在(zai)多種可能存(cun)在(zai)的風險時,需要使用多個(ge)檢(jian)測(ce)(ce)器(qi)(qi)單獨挨個(ge)檢(jian)測(ce)(ce)。每(mei)個(ge)檢(jian)測(ce)(ce)器(qi)(qi)都有其擅長(chang)檢(jian)測(ce)(ce)的方(fang)面(mian),可以經(jing)過(guo)初步分析之后(hou)確定大致地方(fang)向,選擇(ze)適(shi)合地檢(jian)測(ce)(ce)器(qi)(qi)來做檢(jian)測(ce)(ce)。

以(yi)上(shang)就(jiu)是(shi)關于(yu)Sanitizer的一些(xie)簡單(dan)介(jie)紹及(ji)使(shi)用(yong)的分享,更多的關于(yu)Sanitizer的資料可查閱://github.com/google/sanitizers/wiki/

碼字不易,如(ru)果文(wen)章(zhang)對你(ni)有幫助(zhu)!

聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 2
關注 30
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧