Valgrind使用

C/C++内存管理一直都是程序员最头痛的事情,内存越界、数组越界、内存泄漏、内存溢出、野指针、空指针...,随便一个问题都可能让程序崩溃。而且往往问题的源头都比较隐蔽,让人很难排查出问题的根源所在。
  想要解决这个问题,还得从问题的根源入手。valgrind是一个强大的内存管理工具,常用来检测内存泄漏和内存的非法使用,用好了可以很好的从根源上解决c/c++内存管理的问题

1 Valgrind在PC机上的使用
        1.1 Valgrind在PC上的安装

下载

wget  https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2

解压

tarxjvfvalgrind-3.15.0.tar.bz2

cd valgrind-3.15.0

配置

./configure

编译

make

安装

make install

查看版本

valgrind–version

输出如下信息说明安装成功

valgrind-3.15.0

        1.2 使用Valgrind检测内存

先准备一个测试文件memtest.c

该程序有两处错误:第18行发生了越界错误,test2()没有翻译指针p。

编译程序,加上-g可以准确报错出错的行数。

gccmemtest.c -g -o memtest

使用valgrind|检查内存

valgrind --tool=memcheck  --leak-check=full ./memtest

输出:

==29683== Memcheck, a memory error detector

==29683== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

==29683== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info

==29683== Command: ./memtest

==29683==

test memory

test free ...

==29683== Invalid write of size 2

==29683==    at 0x108759: test (memtest.c:18)

==29683==    by 0x10879D: main (memtest.c:26)

==29683==  Address 0x522f504 is 4 bytes inside a block of size 5 alloc'd

==29683==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==29683==    by 0x10874A: test (memtest.c:17)

==29683==    by 0x10879D: main (memtest.c:26)

==29683==

malloc test in test2

exit ......

==29683==

==29683== HEAP SUMMARY:

==29683==     in use at exit: 20 bytes in 1 blocks

==29683==   total heap usage: 4 allocs, 3 frees, 1,113 bytes allocated

==29683==

==29683== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1

==29683==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==29683==    by 0x1086E3: test2 (memtest.c:7)

==29683==    by 0x108774: test (memtest.c:21)

==29683==    by 0x10879D: main (memtest.c:26)

==29683==

==29683== LEAK SUMMARY:

==29683==    definitely lost: 20 bytes in 1 blocks

==29683==    indirectly lost: 0 bytes in 0 blocks

==29683==      possibly lost: 0 bytes in 0 blocks

==29683==    still reachable: 0 bytes in 0 blocks

==29683==         suppressed: 0 bytes in 0 blocks

==29683==

==29683== For counts of detected and suppressed errors, rerun with: -v

==29683== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

Valgrind检查到一处非法写入内存Invalid write of size 2,出现在代码at 0x108759: test (memtest.c:18)。strcpy(ps,"ABCDE");拷贝了五个字符,再加一个’/0’,发生越界。

LEAK SUMMARY显示Valring检查到一处内存泄露,泄露了20个字节。

test2()分配了20个字节的内存,但是没有释放该内存。

修复这两个问题,再次编译运行。

摘要表明,程序分配了4次内存,释放了4次,所有的堆空间都被释放,没有内存泄露。

​​​​​​​        1.3 使用Valgrind检测持续内存泄露

准备一个测试文件mem_run.c

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>



void *thread_function(void *arg);



char message[] = "Hello World";



int main() {

int res;

pthread_ta_thread;

void *thread_result;

res = pthread_create(&a_thread, NULL, thread_function, (void *)message);

if (res != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

    }

printf("Waiting for thread to finish...\n");

res = pthread_join(a_thread, &thread_result);

if (res != 0) {

perror("Thread join failed");

exit(EXIT_FAILURE);

    }

printf("Thread joined, res %d, it returned %s\n", res, (char *)thread_result);

printf("Message is now %s\n", message);

exit(EXIT_SUCCESS);

}



void *thread_function(void *arg) {



char *p = NULL;

inti = 0;

while(1){

        p = (char *)malloc(sizeof(char) * 10);

strcpy(p,"1234");

i ++;

printf("i = %d\n", i);

sleep(1);



    }

}

thread_function持续地分配内存,每次分配10个字节,但不释放。

编译运行

gcc mem_run.c -g -o mem_run -lpthread

valgrind --tool=memcheck --leak-check=full --log-file=./valgrind_report.log ./mem_run

这次将log输出到文件valgrind_report.log中。

              运行6秒钟后,按ctrl+c终止程序,查看valgrind_report.log。

摘要表明6处共60个字节的内存泄露了。

2 ​​​​​​​Valgrind在嵌入式系统EU项目上的使用
        2.1编译安装

       下载

wget  https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2

解压

tarxjvfvalgrind-3.15.0.tar.bz2

进入valgrind目录

cd valgrind-3.15.0

配置

修改configure armv7*) 改成 armv7*|arm)

./configure --prefix=/home/yangkemeng/valgrind_install --host=arm-linux \

CC=/home/yangkemeng/eu/ti_components/os_tools/linux/linaro/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc \

CXX=/home/yangkemeng/eu/ti_components/os_tools/linux/linaro/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++

--prefix指定安装目录,--host 指定芯片架构,CC和CXX指定交叉编译器路径,不可使用相对路径。

输出如下表明配置成功。

编译

Make

安装

Make install

安装后valgrind_install目录下多了5个目录bin 、 include、  lib  libexec、  share

​​​​​​​​​​​​​​        2.2 Valgrind移植到EU开发板

将valgrind_install目录拷贝到开发板的/opt/vision_sdk/目录,

给valgrind_install目录加上可执行权限

chmod-R +x valgrind_install

编辑/etc/profile添加下面两行:

export VALGRIND_LIB=/opt/vision_sdk/valgrind_install/lib/valgrind

export PATH=/opt/vision_sdk/valgrind_install/bin:$PATH

执行如下命令,使环境变量生效

Source /etc/profile

查看valgrind版本,执行valgrind–version,若是输出valgrind-3.15.0,说明移植成功。

​​​​​​​​​​​​​​        2.3 Eu开发板子上测试Valgrind

使用交叉编译器编译之前的memtest.c文件,将生成的memtest拷贝到开发板

../eu/ti_components/os_tools/linux/linaro/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -g memtest.c -o memtest

添加可执行权限

chmod 777 memtest

使用Valgrind检查内存问题

valgrind  --tool=memcheck --leak-check=full --log-file=./valgrind_report.log ./memtest

 3 小结

Valgrind是检查内存问题的有力工具,在项目中使用和推广可以让代码的稳定性可靠性大大提高。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值