版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、代碼檢查工具一內(nèi)存泄漏的發(fā)生方式1).常發(fā)性2).偶發(fā)性3).一次性4) .隱式二代碼檢查的方式代碼檢查的方式分為靜態(tài)代碼檢查(Static program analysis)和動(dòng)態(tài)代碼檢查(Dynamic program analysis)。三動(dòng)態(tài)代碼檢查Valgrind簡單用法1).valgrind包含的工具.memcheck最常用的工具,也是valgrind默認(rèn)的工具。用來檢測程序中出現(xiàn)的內(nèi)存問題,所有對內(nèi)存的讀寫都會(huì)被檢測到。一切對malloc()/free() 、new/delete的調(diào)用都會(huì)被捕獲,所以它能檢測以下問題:Ø 對未初始化內(nèi)存的使用Ø 讀/寫釋放后的
2、內(nèi)存塊Ø 讀/寫超出malloc分配的內(nèi)存塊Ø 讀/寫不適當(dāng)?shù)臈V袃?nèi)存塊Ø 內(nèi)存泄漏,指向一塊內(nèi)存的指針永遠(yuǎn)丟失Ø 不正確的malloc/free或new/delete匹配Ø Memcpy()相關(guān)函數(shù)中的dst和src指針重疊。.callgrind,它不需要在編譯源碼時(shí)附加特殊選項(xiàng),但推薦加上調(diào)試選項(xiàng),callgrind搜集程序運(yùn)行時(shí)的一些數(shù)據(jù),建立函數(shù)調(diào)用關(guān)系圖,還可以有選擇的進(jìn)行cache模擬,在運(yùn)行結(jié)束時(shí),它會(huì)把分析數(shù)據(jù)寫入一個(gè)文件。簡而言之,它主要用來檢查程序中函數(shù)調(diào)用過程中出現(xiàn)的問題。cachegrind,它模擬CPU中的一級(jí)緩存和二
3、級(jí)緩存,能夠精確的指出程序中cache的丟失和命中。如果需要,它還能為我們提供cache丟失的次數(shù),內(nèi)存引用次數(shù),以及每行代碼、每個(gè)函數(shù)、每個(gè)模塊、整個(gè)程序產(chǎn)生的指令數(shù)。對優(yōu)化程序有很大幫助。helgrind,它主要用來檢查多線程程序中出現(xiàn)的競爭問題。Helgrind尋找內(nèi)存中被多個(gè)線程訪問而又沒有一貫加鎖的區(qū)域,這些區(qū)域往往是線程之間失去同步的地方。而且會(huì)導(dǎo)致難以發(fā)掘的錯(cuò)誤。massif,堆棧分析器,它能測量程序在堆棧中使用了多少內(nèi)存,告訴我們堆塊、堆管理塊和棧的大小。它能幫助我們減少內(nèi)存的使用,在帶有虛擬內(nèi)存的現(xiàn)代系統(tǒng)中,它還能加速我們的程序運(yùn)行,減少程序停留在交換區(qū)中的幾率。.exten
4、sion。可以利用core提供的功能,自己編寫特定的內(nèi)存調(diào)試工具。2).valgrind的使用Valgrind valgrind-options your-prog your-prog-options選項(xiàng)作用-h/-help顯示幫助信息-version顯示valgrind內(nèi)核版本-q/-quiet安靜的運(yùn)行,只打印錯(cuò)誤信息-v /-verbose打印更詳細(xì)的信息-tool=default : memcheck運(yùn)行valgrind中的工具,默認(rèn)memcheck.-leak-check=no|summary|full 要求對leak列出詳細(xì)信息default:summary-log-file=&l
5、t;file> Path+日志信息文件3).使用示例.未釋放內(nèi)存,數(shù)組越界.sample.c#include <stdlib.h>void fun()int *p = (int *)malloc(10*sizeof(int);p10=0;int main(int argc , char *argv)fun();return 0;1.編譯:gcc g sample.c o sample2.使用valgrind:valgrind -leak-check=full ./sample輸出信心分析如下圖所示:示例程序中有兩個(gè)問題,一是fun()函數(shù)中動(dòng)態(tài)申請的堆內(nèi)存沒有釋放。二是對堆內(nèi)
6、存的訪問越界。.使用未初始化的內(nèi)存。badloop.c#include <stdio.h>int main(void)int a5;int i , s;a0 = a1 = a2 = a3 = a4 =0;for(i = 0 ; i < 5; i+)s += ai;if(s = 168)printf("sum is %dn" , s);return 0;1.編譯:gcc g badloop.c o badloop2.使用valgrind:valgrind -leak-check=full ./badloop輸出信心分析如下圖所示:.內(nèi)存讀寫越界。badacc
7、.c#include <stdio.h>#include <stdlib.h>int main(void)int len = 4 , i;int *pt = (int *)malloc(len*sizeof(int);int *p = pt;for(i = 0 ; i < len ; i+)p+;*p = 5;printf("the value of p equal:%dn" , *p);return 0;1.編譯:gcc g badacc.c o badacc2.使用valgrind:valgrind -leak-check=full ./b
8、adacc輸出信心分析如下圖所示:.內(nèi)存覆蓋。badlap.cpp#include <stdio.h>#include <stdlib.h>#include <string.h>int main(int argc , char *argv)char x50;int i;for(i = 0 ; i < 50; i+)xi = i+1;strncpy(x+20 , x , 20);strncpy(x+20 , x , 21);strncpy(x , x+20 , 20);strncpy(x , x+20 , 21);x39 = '0'str
9、cpy(x , x+20);x39 = 39;x40 = '0'strcpy(x , x+20);return 0;1.編譯:g+ g badlap.c o badlap2.使用valgrind -leak-check=full ./badlap輸出信心分析如下圖所示:代碼畫紅線部分地址相差20,但是拷貝長度卻是21,這樣就會(huì)覆蓋之前的值。Valgrind也很精確的檢測出了這一點(diǎn)。.動(dòng)態(tài)內(nèi)存管理錯(cuò)誤。badmac.cpp常見的內(nèi)存動(dòng)態(tài)管理錯(cuò)誤:l 申請和釋放不一致(malloc/alloc/realloc申請用free。new用delete)l 申請和釋放不匹配,申請了多少內(nèi)存
10、,在使用完成后就要釋放多少。如果沒有釋放或者少釋放了就是內(nèi)存泄漏,多釋放了也會(huì)產(chǎn)生問題。l 釋放后仍然讀寫。#include <stdlib.h>#include <stdio.h>int main(int argc , char *argv)int i;char *p = (char *)malloc(10);char *pt = p;for(i = 0 ; i < 10 ; i+)pi = 65+i;delete p;pt1 = 'x'free(pt);return 0;1.編譯:g+ g badmac.c o badmac2.使用valgri
11、nd -leak-check=full ./badmac輸出信心分析如下圖所示:由圖可以看出,valgrind準(zhǔn)確定位出這三個(gè)錯(cuò)誤。.內(nèi)存泄漏內(nèi)存泄漏(Memory leak)指的是在程序中動(dòng)態(tài)申請的內(nèi)存,使用完成后即沒有釋放,又無法被程序的其它部分訪問。Tree.h#ifndef _BADLEAK_#define _BADLEAK_typedef struct _node struct _node *l;struct _node *r;char v;node;node *mk(node *l , node *r , char val);void nodefr(node *n);#endifT
12、ree.cpp#include <stdlib.h>#include "tree.h"node *mk(node *l , node *r , char val)node *f = (node *)malloc(sizeof(node);f->l = l;f->r = r;f->v = val;return f;void nodefr(node *n)if(n)nodefr(n->l);nodefr(n->r);free(n);Badleak.cpp#include <stdio.h>#include "tre
13、e.h"int main(int argc , char *argv)node *tree1 , *tree2 , *tree3;printf("testn");tree1 = mk(mk(mk(0,0,'3'),0,'2'),0,'1');tree2 = mk(0,mk(0,mk(0,0,'6'),'5'),'4');tree3 = mk(mk(tree1,tree2,'8'),0,'7');return 0;Makefilebadle
14、ak:badleak.o tree.og+ -o badleak badleak.o tree.obadleak.o:badleak.cpp g+ -g -c badleak.cpptree.o:tree.cpp g+ -g -c tree.cppclean:rm -rf *.orm -rf badleak至此,valgrind常用的方法已總結(jié)完畢,置于valgrind的其它工具使用在此就不一 一列舉。四靜態(tài)代碼檢查Splint靜態(tài)程序分析(static program analysis):靜態(tài)程序分析是指使用自動(dòng)化工具軟件對程序源代碼進(jìn)行檢查,以分析程序行為的技術(shù),應(yīng)用程序的正確性、安全缺陷
15、檢測、程序優(yōu)化等。它的特點(diǎn)是不執(zhí)行程序。1.Splint的檢測范圍:ü 可能的空指針ü 在釋放內(nèi)存之后使用了該指針ü 賦值次序問題ü 拼寫錯(cuò)誤ü 被零除ü 失敗的case語句(遺漏了break語句)ü 不可移植的代碼ü 宏定義參數(shù)沒用圓括號(hào)ü 符號(hào)的丟失ü 異常的表達(dá)式ü 變量沒有初始化ü 轉(zhuǎn)換類型不一致ü 可疑的判斷語句(例如:if(x=0))ü Printf/scanf的格式檢查2.Splint的使用在Linux命令行下,splint的使用很簡單,檢測
16、文件*.c,用法如下:splint *.c檢查控制splint提供了三種方式可進(jìn)行檢查的控制,分別是.splintrc配置文件、flags標(biāo)志和格式化注釋。flags:splint支持幾百個(gè)標(biāo)志用來控制檢查和消息報(bào)告,使用時(shí)標(biāo)志前加+或-,'+'標(biāo)志開啟這個(gè)標(biāo)志,'-'表示關(guān)閉此標(biāo)志,下面例子展示了flags標(biāo)志的用法:splint -showcol a.c /在檢測a.c時(shí),告警消息中列數(shù)不被打印splint -varuse a.c /在檢測a.c時(shí),告警消息中未使用變量告警不被打印.splintrc配置文件:在使用源碼安裝splint之后,.splintrc
17、文件將被安裝在主目錄下,.splintrc文件中對一些標(biāo)志作了默認(rèn)的設(shè)定,命令行中指定的flags標(biāo)志會(huì)覆蓋.splintrc文件中的標(biāo)志。格式化注釋:格式化注釋提供一個(gè)類型、變量或函數(shù)的格外的信息,可以控制標(biāo)志設(shè)置,增加檢查效果,所有格式化注釋都以/*開始,*/結(jié)束,比如在函數(shù)參數(shù)前加/*null*/,表示該參數(shù)可能是NULL,做檢測時(shí),splint會(huì)加強(qiáng)對該參數(shù)的值的檢測。3.使用示例.認(rèn)識(shí)splint輸出的警告消息#include <stdlib.h>int func_splint_msg1(void)int a;return 0;int func_splint_msg2(v
18、oid)int *a = (int*)malloc(sizeof(int);a = NULL;return 0;直接運(yùn)行:splint sample.c使用空指針null_point.c#include <stdio.h>int func_null_point(void)int *a = NULL;return *a;直接運(yùn)行:splint null_point.c.轉(zhuǎn)換類型不一致問題types.c#include <stdio.h>void splint_types(void)short a = 0;long b = 32768;a = b;return ;直接運(yùn)行:
19、splint types.c.內(nèi)存管理memory_managment.c#include <stdio.h>#include <stdlib.h>/當(dāng)有其他指針引用當(dāng)時(shí)候,釋放一塊空間void memory_management(void)int *a = (int *)malloc(sizeof(int);int *b = a;free(a);*b = 0;直接運(yùn)行:splint memory_managment.c#include <stdio.h>#include <stdlib.h>void memory_management(void)int *a = (int *)malloc(sizeof(int);a = NULL;直接運(yùn)行:splint memory_managment.c緩存邊界buffersize.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 20991-2024足部防護(hù)鞋的測試方法
- RNF5-agonist-1-生命科學(xué)試劑-MCE-3083
- Acremine-F-生命科學(xué)試劑-MCE-8674
- 二零二五年度船舶船員勞動(dòng)合同及船舶航行風(fēng)險(xiǎn)承擔(dān)合同
- 2025年度汽車美容店員工勞動(dòng)合同簽訂與解除流程合同
- 2025年度航空設(shè)施面積差額補(bǔ)充合同
- 2025年度汽車銷售合同和購車售后服務(wù)質(zhì)量監(jiān)控協(xié)議
- 施工日志填寫中的質(zhì)量和安全事故記錄方法
- 運(yùn)動(dòng)與心理健康如何通過鍛煉提升幸福感
- 教育科技下的道德與法治教育融合探討
- (完整版)4.19天體運(yùn)動(dòng)綜合習(xí)題(帶答案)
- 工法培訓(xùn)課件
- 液壓式隨鉆震擊器設(shè)計(jì)
- 空氣能熱泵系統(tǒng)設(shè)計(jì)與安裝融資計(jì)劃書
- 2021中考地理真題試卷 山東省煙臺(tái)地理含答案
- 非法捕撈水產(chǎn)品罪
- 新概念第一冊單詞匯總帶音標(biāo)EXCEL版
- 作用于血液及造血器官的藥 作用于血液系統(tǒng)藥物
- 心肺復(fù)蘇(最全版)完整版
- 春節(jié)節(jié)后施工復(fù)工安全培訓(xùn)
- GB/T 3478.1-1995圓柱直齒漸開線花鍵模數(shù)基本齒廓公差
評(píng)論
0/150
提交評(píng)論