Linux 内存检测valgrind&&单元测试模块测试

sudo  apt-get install valgrind   安装

Memcheck是valgrind   中得一个工具

 用来检测c/c++程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,它能检测以下问题: 

\1. 对未初始化内存的使用; 


\2./写释放后的内存块;

 
\3./写超出malloc等分配的动态内存范围; 


\4./写不适当的栈中内存块; 


\5. 内存泄漏,指向一块内存的指针永远丢失; 


\6. 不正确的malloc/free或new/delete匹配; 



\7.  memcpy()相关函数中的dst和src指针重叠问题。





1.在编译程序的时候打开调试模式(gcc编译器的-g选项),以便显示行号,编译时去掉-O1 -O2等优化选项;检查的是C++程序的时候,考虑加上选项: -fno-inline ,这样它函数调用链会很清晰

 

\2. 执行:valgrind --tool=memcheck --leak-check=full  --log-file=./log.txt  ./YourProgram(编译之前加上-g得选项 如gcc -g  xxx  -o  xxx) log.txt 就是日志文件

 

3.程序运行结束,查看 log.txt 中的结果。



valgrind --help  //获取帮助``

文件 -s “年//日  时:分:秒”//设置时间 也可以直接时分秒

*结果分析*

Valgrind(memcheck)包含这7类错误,黑体为一般的错误提示:

1.illegal read/illegal write errors 非法读取/非法写入错误

2.use of uninitialised values 使用未初始化的区域

3.use of uninitialised or unaddressable values in system calls 系统调用时使用了未初始化或不可寻址的地址

4.illegal frees 非法的释放

5.when a heap block is freed with an inappropriate deallocation function 分配和释放函数不匹配

6.overlapping source and destination blocks 源和目的内存块重叠

7.memory leak detection 内存泄漏检测

​ 7.1 Still reachable ​ 内存指针还在还有机会使用或者释放,指针指向的动态内存还没有被释放就退出了

7.2 Definitely lost 
确定的内存泄露,已经不能够访问这块内存


7.3 Indirectly lost 
指向该内存的指针都位于内存泄露处


7.4 Possibly lost 
可能的内存泄露,仍然存在某个指针能够访问某块内存,但该指针指向的已经不是该内

存首位置
7.5 Suppressed 某些库产生的错误不予以提示,这些错误会被统计到suppressed项目


搭建测试框架 单元测试模块测试

gtest下载地址: https://github.com/google/googletest

下载方法是:git clone https://github.com/google/googletest.git 安装方法是:

$ cd googletest

注意:如果在make 过程中报错,可在CMakeLists.txt 中增加如下行,再执行下面的命令:
SET(CMAKE_CXX_FLAGS “-std=c++11”)

$ cmake .

$ make

然后在lib目录下会生成:libgmock.a libgmock_main.a libgtest.a libgtest_main.a
最后我们再sudo make install。//查看头文件得位置

#include 
#include "sample1.h"//测试的函数头文件
#include "gtest/gtest.h"
namespace {

TEST(FactorialTest, Negative) {//测试负数
    // This test is named "Negative", and belongs to the "FactorialTest"
    // test case.
    EXPECT_EQ(1, Factorial(-5));//测试断言 传入-5应该返回1
    EXPECT_EQ(1, Factorial(-1));
    EXPECT_GT(Factorial(-10), 0);//EQ表示大于
}

TEST(FactorialTest, Zero) {//测试FactorialTest (函数)0
    EXPECT_EQ(1, Factorial(0));
}

TEST(FactorialTest, Positive) {//测试正数
    EXPECT_EQ(1, Factorial(1));
    EXPECT_EQ(2, Factorial(2));
    EXPECT_EQ(6, Factorial(3));
    EXPECT_EQ(40320, Factorial(8));
}

// Tests IsPrime()
TEST(IsPrimeTest, Negative) {
  EXPECT_FALSE(IsPrime(-1));//测试返回值为假
  EXPECT_FALSE(IsPrime(-2));
  EXPECT_FALSE(IsPrime(INT_MIN));
}

TEST(IsPrimeTest, Trivial) {
  EXPECT_FALSE(IsPrime(0));
  EXPECT_FALSE(IsPrime(1));
  EXPECT_TRUE(IsPrime(2));
  EXPECT_TRUE(IsPrime(3));
}

TEST(IsPrimeTest, Positive) {
  EXPECT_FALSE(IsPrime(4));
  EXPECT_TRUE(IsPrime(5));
  EXPECT_FALSE(IsPrime(6));
  EXPECT_TRUE(IsPrime(23));
}
}  // namespace

TEST是gtest的测试宏,我们的测试用例必须按照这样格式写,isPrimeTest是测试套的名字,一个测试套下可以有多个测试用例,那么Positive、Trivial就是我们测试用例的名称,EXPECT_EQ、EXPECT_FALSE和EXPECT_TRUE等等,都是gtest提供的测试断言,比如 EXPECT_EQ(1, Factorial(1));就是表示Factorial(1)和1是不是相等的,如果是则表示EXPECT_EQ会返回成功,否则失败,也即我们测试用例会失败或者成功。

实现测试的main函数,当然我们也可以不用写main函数,那就需要连接gtest_main.a这个库。比如这样子编译:

g++ sample1.cc sample1_unittest.cc -lgtest -std=c++11 -lgtest_main -lpthread -o test1

然后运行测试程序test:

$ ./test
或者自己写一个测试用例

#include 

int main(int argc, char** argv){
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

你可能感兴趣的:(笔记,linux)