亚洲xxxx做受欧美,丰满熟妇bbwhd,无码人妻丰满熟妇区96,无码人妻丰满熟妇区96

Back

AddressSanitizer使用介紹

by WANGWANG


 

1、關(guān)于AddressSanitizer

1.1 引言

也許很多人都聽說過類似這樣的一個(gè)故事:某公司的服務(wù)器每隔3個(gè)月就會(huì)毫無預(yù)兆的崩潰一次,怎么也查不出原因,為了避免崩潰可能引發(fā)的問題,只得每2個(gè)月手動(dòng)重啟一次服務(wù)器。在這類有些靈異的事件背后,以內(nèi)存泄露為代表的一系列內(nèi)存錯(cuò)誤往往就是那個(gè)幕后黑手。


在計(jì)算機(jī)科學(xué)中,內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。內(nèi)存泄漏并非指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯(cuò)誤,失去了對(duì)該段內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。


內(nèi)存泄漏會(huì)導(dǎo)致可用內(nèi)存的數(shù)量減少?gòu)亩档陀?jì)算機(jī)的性能。過多的可用內(nèi)存被分配掉會(huì)導(dǎo)致全部或部分設(shè)備停止正常工作,或者應(yīng)用程序崩潰。


其他的內(nèi)存錯(cuò)誤還包括緩沖區(qū)溢出、越界訪問等,此類錯(cuò)誤輕則導(dǎo)致程序計(jì)算錯(cuò)誤,重則引起程序崩潰,在內(nèi)存緊張的嵌入式系統(tǒng)中尤為致命,Google旗下的開源工具AddressSanitizer可以幫助我們檢測(cè)此類錯(cuò)誤。


AddressSanitizer(ASan)是一個(gè)快速的內(nèi)存錯(cuò)誤檢測(cè)工具。它非常快,只拖慢程序兩倍左右。它包括一個(gè)編譯器instrumentation模塊和一個(gè)提供malloc()/free()替代項(xiàng)的運(yùn)行時(shí)庫(kù)。從gcc 4.8開始,AddressSanitizer成為gcc的一部分。


詳細(xì)了解AddressSanitizer信息可以訪問其github項(xiàng)目地址:
https://github.com/google/sanitizers/wiki/AddressSanitizer

 

1.2 AddressSanitizer原理簡(jiǎn)介

AddressSanitizer主要包括兩部分:插樁(Instrumentation)和動(dòng)態(tài)運(yùn)行庫(kù)(Run-time library)。插樁主要是針對(duì)在llvm編譯器級(jí)別對(duì)訪問內(nèi)存的操作(store,load,alloca等),將它們進(jìn)行處理。動(dòng)態(tài)運(yùn)行庫(kù)主要提供一些運(yùn)行時(shí)的復(fù)雜的功能(比如poison/unpoison shadow memory)以及將malloc,free等系統(tǒng)調(diào)用函數(shù)hook住。該算法的思路是:如果想防住Buffer Overflow漏洞,只需要在每塊內(nèi)存區(qū)域右端(或兩端,能防overflow和underflow)加一塊區(qū)域(RedZone),使RedZone的區(qū)域的影子內(nèi)存(Shadow Memory)設(shè)置為不可寫即可。具體的示意圖如下圖所示。

 

 

內(nèi)存映射

AddressSanitizer保護(hù)的主要原理是對(duì)程序中的虛擬內(nèi)存提供粗粒度的影子內(nèi)存(每8個(gè)字節(jié)的內(nèi)存對(duì)應(yīng)一個(gè)字節(jié)的影子內(nèi)存),為了減少overhead,采用了直接內(nèi)存映射策略,所采用的具體策略如下:Shadow=(Mem >> 3) + offset。每8個(gè)字節(jié)的內(nèi)存對(duì)應(yīng)一個(gè)字節(jié)的影子內(nèi)存,影子內(nèi)存中每個(gè)字節(jié)存取一個(gè)數(shù)字k,如果k=0,則表示該影子內(nèi)存對(duì)應(yīng)的8個(gè)字節(jié)的內(nèi)存都能訪問,如果0<k<7,表示前k個(gè)字節(jié)可以訪問,如果k為負(fù)數(shù),不同的數(shù)字表示不同的錯(cuò)誤(e.g. Stack buffer overflow, Heap buffer overflow)。

 

插樁

為了防止buffer overflow,需要將原來分配的內(nèi)存兩邊分配額外的內(nèi)存Redzone,并將這兩邊的內(nèi)存加鎖,設(shè)為不能訪問狀態(tài),這樣可以有效的防止buffer overflow(但不能杜絕buffer overflow)。以下是在棧中插樁的一個(gè)例子。

 

未插樁的代碼:

 

插樁后的代碼:

 

插樁后的代碼:

在動(dòng)態(tài)運(yùn)行庫(kù)中將malloc/free函數(shù)進(jìn)行了替換。在malloc函數(shù)中額外的分配了Redzone區(qū)域的內(nèi)存,將與Redzone區(qū)域?qū)?yīng)的影子內(nèi)存加鎖,主要的內(nèi)存區(qū)域?qū)?yīng)的影子內(nèi)存不加鎖。
free函數(shù)將所有分配的內(nèi)存區(qū)域加鎖,并放到了隔離區(qū)域的隊(duì)列中(保證在一定的時(shí)間內(nèi)不會(huì)再被malloc函數(shù)分配),可檢測(cè)Use after free類的問題。
詳細(xì)了解ASan算法原理可以訪問以下地址:
https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm

 

2、使用方法

環(huán)境:Ubuntu 16.04   gcc 4.8以上
用-fsanitize=address選項(xiàng)編譯和鏈接你的程序;
用-fno-omit-frame-pointer編譯,以在錯(cuò)誤消息中添加更好的堆棧跟蹤。
增加-O1以獲得更好的性能。
下面以簡(jiǎn)單的測(cè)試代碼leaktest.c為例

 

 

在終端中輸入以下命令編譯leaktest.c

 

 

運(yùn)行l(wèi)eaktest,會(huì)打印下面的錯(cuò)誤信息:

 

 

第一部分(ERROR),指出錯(cuò)誤類型detected memory leaks;
第二部分給出詳細(xì)的錯(cuò)誤信息:Direct leak of 80 byte(s) in 1 object(s),以及發(fā)生錯(cuò)誤的對(duì)象名/源文件位置/行數(shù);
第三部分是以上信息的一個(gè)總結(jié)(SUMMARY)。
 

3、設(shè)置檢測(cè)白名單

可以根據(jù)以下的需求設(shè)置ASan檢測(cè)白名單
忽略一個(gè)確定正確的函數(shù)以提高應(yīng)用運(yùn)行速度;
忽略一個(gè)特定功能的函數(shù)(例如:繞過框架邊界穿過線程的堆棧);
忽略已知的問題。

使用no_sanitize_address屬性(Clang3.3及GCC4.8以上版本支持)定義如下的宏命令:

 

4、AddressSanitizer能檢測(cè)的錯(cuò)誤類型(以官方Wiki為準(zhǔn))

請(qǐng)您填寫郵箱地址,以獲得下載權(quán)限。
主站蜘蛛池模板: 厦门市| 天祝| 徐闻县| 西华县| 常州市| 安仁县| 洛阳市| 塘沽区| 湘阴县| 温州市| 东莞市| 赤水市| 宝鸡市| 大安市| 通州市| 江源县| 青海省| 凤翔县| 岗巴县| 长武县| 梅河口市| 鸡东县| 化隆| 宜章县| 繁峙县| 准格尔旗| 招远市| 木里| 兴义市| 沽源县| 宁陵县| 武宣县| 寿阳县| 湄潭县| 淳化县| 彭阳县| 商南县| 玉环县| 三门县| 探索| 疏附县|