2014-04-17 218 views
0

我正在開發內核內存檢查器來查找內核空間中的內存泄漏。linux內核模塊內存檢查器

  1. 我有兩個功能profile_vmalloc和profile_vfree,profile_vmalloc使用vmalloc的分配內存並增加了內存分配信息到一個列表,profile_vfree釋放分配的內存,並從列表中刪除該信息。如何替換vmalloc和vfree,以便在編譯和運行我的模塊時,任何內核模塊分配和釋放內存都將使用我的函數?

  2. 如何使用sysfs創建一個只讀文件,該文件將允許用戶查看內存泄漏摘要?

這是我的代碼是什麼樣子至今

// Linux Kernel headers 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/init.h> 
#include <linux/config.h> 
#include <linux/vmalloc.h> 

#define FILE_NAME_LENGTH   256 
#define vmalloc(size)    profile_malloc (block_size, __FILE__, __LINE__) 
#define vfree(mem_ref)     profile_free(mem_ref) 

struct _MEM_INFO 
{ 
    const void   *address; 
    size_t    size; 
    char    file_name[FILE_NAME_LENGTH]; 
    size_t    length; 
}; 
typedef struct _MEM_INFO MEM_INFO; 

struct _MEM_LEAK { 
    MEM_INFO mem_info; 
    struct _MEM_LEAK * next; 
}; 
typedef struct _MEM_LEAK MEM_LEAK; 



#undef  vmalloc 
#undef  vfree 


static MEM_PROFILER_LIST * ptr_start = NULL; 
static MEM_PROFILER_LIST * ptr_next = NULL; 

/* 
* adds allocated memory info. into the list 
* 
*/ 
void add(MEM_INFO alloc_info) 
{ 

    MEM_PROFILER_LIST * mem_leak_info = NULL; 
    mem_leak_info = (MEM_PROFILER_LIST *) malloc (sizeof(MEM_PROFILER_LIST)); 
    mem_leak_info->mem_info.address = alloc_info.address; 
    mem_leak_info->mem_info.size = alloc_info.size; 
    strcpy(mem_leak_info->mem_info.file_name, alloc_info.file_name); 
    mem_leak_info->mem_info.line = alloc_info.line; 
    mem_leak_info->next = NULL; 

    if (ptr_start == NULL) 
    { 
     ptr_start = mem_leak_info; 
     ptr_next = ptr_start; 
    } 
    else { 
     ptr_next->next = mem_leak_info; 
     ptr_next = ptr_next->next;    
    } 

} 

/* 
* remove memory info. from the list 
* 
*/ 
void erase(unsigned pos) 
{ 

    unsigned int i = 0; 
    MEM_PROFILER_LIST * alloc_info, * temp; 

    if(pos == 0) 
    { 
     MEM_PROFILER_LIST * temp = ptr_start; 
     ptr_start = ptr_start->next; 
     free(temp); 
    } 
    else 
    { 
     for(i = 0, alloc_info = ptr_start; i < pos; 
      alloc_info = alloc_info->next, ++i) 
     { 
      if(pos == i + 1) 
      { 
       temp = alloc_info->next; 
       alloc_info->next = temp->next; 
       free(temp); 
       break; 
      } 
     } 
    } 
} 

/* 
* deletes all the elements from the list 
*/ 
void clear() 
{ 
    MEM_PROFILER_LIST * temp = ptr_start; 
    MEM_PROFILER_LIST * alloc_info = ptr_start; 

    while(alloc_info != NULL) 
    { 
     alloc_info = alloc_info->next; 
     free(temp); 
     temp = alloc_info; 
    } 
} 

/* 
* profile of vmalloc 
*/ 
void * profile_vmalloc (unsigned int size, const char * file, unsigned int line) 
{ 
    void * ptr = vmalloc (size); 
    if (ptr != NULL) 
    { 
     add_mem_info(ptr, size, file, line); 
    } 
    return ptr; 
} 


/* 
* profile of free 
*/ 
void profile_free(void * mem_ref) 
{ 
    remove_mem_info(mem_ref); 
    free(mem_ref); 
} 

/* 
* gets the allocated memory info and adds it to a list 
* 
*/ 
void add_mem_info (void * mem_ref, unsigned int size, const char * file, unsigned int line) 
{ 
    MEM_INFO mem_alloc_info; 

    /* fill up the structure with all info */ 
    memset(&mem_alloc_info, 0, sizeof (mem_alloc_info)); 
    mem_alloc_info.address = mem_ref; 
    mem_alloc_info.size = size; 
    strncpy(mem_alloc_info.file_name, file, FILE_NAME_LENGTH); 
    mem_alloc_info.line = line; 

    /* add the above info to a list */ 
    add(mem_alloc_info); 
} 

/* 
* if the allocated memory info is part of the list, removes it 
* 
*/ 
void remove_mem_info (void * mem_ref) 
{ 
    unsigned int i; 
    MEM_PROFILER_LIST * leak_info = ptr_start; 

    /* check if allocate memory is in our list */ 
    for(i = 0; leak_info != NULL; ++i, leak_info = leak_info->next) 
    { 
     if (leak_info->mem_info.address == mem_ref) 
     { 
      erase (i); 
      break; 
     } 
    } 
} 

/* 
* writes a memory leak summary to a file 
*/ 
void mem_leak_summary(void) 
{ 
    unsigned int i; 
    MEM_PROFILER_LIST * mem_output; 

    FILE * fp_write = fopen (SUMMARY_FILE, "wt"); 
    char info[1024]; 

    if(fp_write != NULL) 
    { 

     fwrite(info, (strlen(info) + 1) , 1, fp_write); 
     sprintf(info, "%s\n", "-----------------------------------"); 
     fwrite(info, (strlen(info) + 1) , 1, fp_write); 

     for(mem_output= ptr_start; mem_output!= NULL; mem_output= mem_output->next) 
     { 
      sprintf(info, "address : %d\n", leak_info->mem_output.address); 
      fwrite(info, (strlen(info) + 1) , 1, fp_write); 
      sprintf(info, "size : %d bytes\n", leak_info->mem_output.size);   
      fwrite(info, (strlen(info) + 1) , 1, fp_write); 
      sprintf(info, "line : %d\n", leak_info->mem_output.line); 
      fwrite(info, (strlen(info) + 1) , 1, fp_write); 
      sprintf(info, "%s\n", "-----------------------------------"); 
      fwrite(info, (strlen(info) + 1) , 1, fp_write); 
     } 
    } 
    clear(); 
} 

static int __init profiler_init(void) 
{ 
    return 0; 
} 

static void __exit profiler_cleanup(void) 
{ 
    printk("profiler module uninstalled\n"); 
} 

module_init(profiler_init); 
module_exit(profiler_cleanup); 
MODULE_LICENSE("GPL"); 
+0

請教關於http://kernelnewbies.org/ –

回答

0

如何更換vmalloc的和vfree所以 ,當我編譯和運行我的模塊的任何內核模塊分配和 釋放內存會使用我的功能?

步驟1.在調用vmalloc & vfree文件,定義宏:

#define vmalloc(x) profile_vmalloc(x) 
#define vfree(x) profile_vfree(x) 

這將確保你的函數被調用。

第2步:在您定義的profile_*函數中,您是否記賬並調用實際的vmalloc/vfree函數。

你已經在做第2步,所以你只需要採取的步驟的護理1.

+0

感謝您與步驟1中的幫助下,我認爲這將解決我的問題,但我仍然有一個步驟2的問題,我試圖寫入文件在我的代碼中的方式可能會在用戶空間但在內核空間沒有工作,你能幫我一下嗎? –