C 語言的記憶體漏洞檢查

高等 C 語言

簡介

字串

指標與陣列

函數

結構

物件導向

記憶體

檔案

錯誤處理

巨集處理

C 與組合語言

資料結構

動態字串

動態陣列

鏈結串列

雜湊表

開發環境

Make

Cygwin

MinGW

DevC++

wxDevC++

編譯器

gcc 編譯器

TinyCC 編譯器

LCC 編譯器

應用主題

CGI 程式

GNU 程式

視窗程式

影像處理

練習題

訊息

相關網站

參考文獻

最新修改

簡體版

English

在 C 語言中,如果有人用 malloc() 等函數分配了記憶體,卻忘了用 free() 等函數進行釋放,那就會產生記憶體漏洞。要解決這個問題,必須遵循幾個原則,第一個是程式紀律的問題,例如一個很好的習慣是,採用物件導向的寫法,然後在物件的建構函數中分配記憶體,並在解構函數中,釋放該物件所分配的所有記憶體。

第二個原則是程式測試的問題,您可以使用記憶體檢查函數,進行記憶體漏洞檢查,像是 Linux 當中就有 mtrace 這樣的套件可以使用,您只要引用 <mcheck.h> 這個標頭檔即可,以下是一個使用 mtrace 進行記憶體檢查的範例。

mtrace 的使用 (Linux)

檔案:leak.c

#include <stdlib.h>
#include <mcheck.h> // mtrace 的標頭檔
 
int main() { 
    int *a;
    mtrace(); // 啟用 mtrace
    a = malloc(sizeof(int));  分配記憶體
    *a = 7; 
    // 忘了釋放
    return EXIT_SUCCESS;
}

執行方法:

setenv MALLOC_TRACE  /home/karthik/temp/trace.txt // 設定 mtrace 的環境變數 MALLOC_TRACE
$ gcc -g -Wall -ansi -pedantic leak.c -o leak.o       // 編譯
$ ./leak                                                // 執行
$ mtrace leak.o /home/karthik/temp/trace.txt        // 追蹤記憶體漏洞
Memory not freed:
-----------------
   Address     Size     Caller
0x08049910      0x4  at /home/karthik/tips/leak.c:9 // 發現在 leak.c 的第 9 行,有 4 byte 沒釋放

簡單的檢查方法

假如您沒有辦法使用像 mtrace 這種由系統所提供的記憶體檢查方法,也可以自己製作一個很簡單的版本。為了示範這種作法,我們設計了 new(), del() 與 mcheck() 等三個巨集,以示範這種簡單的漏洞檢查法。

程式範例:mcheck.c

#include <stdio.h>
#include <stdlib.h>

int newSize = 0;
int delSize = 0;
#define new(TYPE, n) malloc(n*sizeof(TYPE)); newSize+=n*sizeof(TYPE)
#define del(ptr, TYPE, n) free(ptr); delSize+=n*sizeof(TYPE)
#define mcheck() printf("Memory:newSize=%d delSize=%d leakSize=%d\n", \
                        newSize, delSize, newSize-delSize);

int main() {
  int *ip = new(int, 10);
  char *cp = new(char, 5);
  del(ip, int, 10);
  mcheck();
}

執行結果:

D:\cp>gcc mcheck.c -o mcheck

D:\cp>mcheck
Memory:newSize=45 delSize=40 leakSize=5

有了這樣的函數,您就可以知道是否有記憶體漏洞的存在了,雖然不像 mtrace 那樣可以直接告訴您產生漏洞的程式位置,但至少可以讓您檢查是否存在記憶體漏洞。

來自 jserv 的建議

mtrace 是 glibc (GNU C Library) 提供的記憶體分析工具,但 Linux (kernel) 不見得搭配
glibc,實際可用 uClibc, musl-libc, bionic libc, diet libc 等等。後幾者就沒有 mtrace
這樣方便的機制了。

參考文獻

  1. Identifying Memory Leaks in Linux for C++ Programs — http://www.devx.com/tips/Tip/20915

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License