linux访问非法内存,Linux环境定位C程序内存泄露以及非法访问的方法

网上有很多例子,这里主要依照工作中的使用来记录一下心得。通过搜索可以搜到mcheck、mtrace、valgrind等等各种方法。这里记录一下:

1 mcheck

具体可以搜《Linux系统下借助mcheck实现c/c++程序的堆内存异常检查》这篇文章,比较详细。我比较喜欢用其中的b、c两种:

b. 在makefile中使用-lmcheck来链接程序。优点:无需在源码中显式调用mcheck,且一定可以保证mcheck先于malloc被调用;缺点:程序需要重新编译。 c. 通过设置环境变量MALLOC_CHECK_实现:export MALLOC_CHECK_=0表示检测到的堆内存异常都被忽略;export MALLOC_CHECK_=1表示检测到异常时,向stderr打印相关信息,程序继续运行;export MALLOC_CHECK_=2表示检测到异常时,程序立即abort。定位堆内存问题时,推荐设置为2,这样可以在异常发生时及时保留最近的现场。优点:无需改代码,亦无需重新编译;缺点:需设置环境变量,无法打印出堆内存一致性状态,只是简单的abort进程。

其中b的方法,在实际应用中发现有时会导致进程大量占用内存,具体原因没有查出。

其中c的方法,需要注意进程不能以守护方式后台运行。

2 warp

具体可以搜索《使用__wrap_malloc查看内存使用》这篇文章。

相关代码:

// wrap.c

#include

#include

void* __real_malloc(size_t size); // 只声明不定义__real_malloc

void* __wrap_malloc(size_t size) // 定义__wrap_malloc

{

printf("__wrap_malloc called, size:%zd\n", size); // log输出

return __real_malloc(size); // 通过__real_malloc调用真正的malloc

}

// test.c

#include

#include

int main()

{

char* c = (char*)malloc(sizeof(char)); // 调用malloc

printf("c = %p\n", c);

free(c); // 调用free,防止内存泄漏

return 0;

}

gcc -c wrap.c test.c

gcc -Wl,--wrap,malloc -o test wrap.o test.o // 链接参数-Wl,--wrap,malloc

3 hook

参看 https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html 。

在实际项目中,用到的C进程是opensaf拉起来的,涉及到.so和多线程。通过编写实验函数,证明hook的方式,.so中以及子线程中也是有效的。

相关代码:

//test.c

#include

#include

#include

#include

#include "test_so.h"

/* Prototypes for our hooks. */

static void my_init_hook (void);

static void *my_malloc_hook (size_t, const void *);

static void my_free_hook (void*, const void *);

void *old_malloc_hook = NULL;

void *old_free_hook = NULL;

static void

my_init (void)

{

old_malloc_hook = __malloc_hook;

old_free_hook = __free_hook;

__malloc_hook = my_malloc_hook;

__free_hook = my_free_hook;

}

static void *

my_malloc_hook (size_t size, const void *caller)

{

void *result;

/* Restore all old hooks */

__malloc_hook = old_malloc_hook;

__free_hook = old_free_hook;

/* Call recursively */

result = malloc (size);

/* Save underlying hooks */

old_malloc_hook = __malloc_hook;

old_free_hook = __free_hook;

/* printf might call malloc, so protect it too. */

printf ("malloc (%u) returns %p\n", (unsigned int) size, result);

/* Restore our own hooks */

__malloc_hook = my_malloc_hook;

__free_hook = my_free_hook;

return result;

}

static void

my_free_hook (void *ptr, const void *caller)

{

/* Restore all old hooks */

__malloc_hook = old_malloc_hook;

__free_hook = old_free_hook;

/* Call recursively */

free (ptr);

/* Save underlying hooks */

old_malloc_hook = __malloc_hook;

old_free_hook = __free_hook;

/* printf might call free, so protect it too. */

printf ("freed pointer %p\n", ptr);

/* Restore our own hooks */

__malloc_hook = my_malloc_hook;

__free_hook = my_free_hook;

}

void thread(void)

{

int *a = malloc(20);

printf("thread malloc\n");

free(a);

test_so();

return;

}

int main ()

{

pthread_t id;

pthread_create(&id, NULL, (void*)thread, NULL);

my_init();

int *b = malloc(30);

free(b);

pthread_join(id, NULL);

return 0;

}

//test_so.h

void test_sa();

//test_so.c

#include

#include

#include

#include "test_so.h"

void test_so()

{

int *p = malloc(100);

printf("test so malloc!\n");

free(p);

printf("test so free!\n");

return;

}

//编译:

gcc test_so.c -fPIC -shared -o libtest.so

gcc test.c -L. -ltest -lpthread -o test

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值