Memcheck错误解释

Memcheck只能检测出两种错误类型:

  • use of illegal addresses
  • use of undefined values

这两种错误类型,足以应对大多数的情况。下面针对这两种类型出现的错误进行解释。


Illegal read / Illegal write errors

 Invalid read of size 1
    at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x4F50018: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
    by 0x109C71: main (argparse_.cc:53)

这表示程序在读取/写入一段Memcheck应该操作的内存。本错误提示中,程序在地址0x109C71读取了一个字节,在程序中的地址是 main (argparse_.cc:53)

Use of uninitialised values

  • 程序中的局部变量没有被初始化就使用了
  • malloc的内存块的内容,在没有写入任何内容之前就使用了,C++中是new运算符。

比如:

    char* chr = static_cast<char*>(::malloc(sizeof(char)));

    std::cout<<"chr:" <<*chr<<std::endl;    
    ::free(chr);

由于没有对::malloc分配的内存进行初始化就使用了,就会导致这个错误。

 Conditional jump or move depends on uninitialised value(s)
    at 0x5250A65: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1241)
    by 0x5244976: fwrite (iofwrite.c:39)
    by 0x4F4FCB3: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
    by 0x4F4FF57: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
    by 0x108A10: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)

其他的的使用没有初始化的变量也会产生这个问题。

    int main(int argc, char const* argv[]) {
        int x;
        printf("x=%d.\n",x);
    }

Illegal frees

即,free/delete次数多于malloc/new
比如对于代码:

    char* chr = static_cast<char*>(::malloc(sizeof(char)));
    std::cout<<"chr:" <<*chr<<std::endl;    
    ::free(chr);
    ::free(chr);
    return 0;

valgrind得到的错误报告就有Invalid free() / delete / delete[] / realloc()

 Invalid free() / delete / delete[] / realloc()
    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x108A3D: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)
  Address 0x5b7dc80 is 0 bytes inside a block of size 1 free'd

Mismatched free() / delete / delete []

  • 释放内存和分配的方式不一致。比如new[]分配的,而采用delete
  • 使用new/malloc分配而采用free/delete释放。

比如代码:

    char* chr = new char[10];
    delete chr;

产生的错误如下:

Mismatched free() / delete / delete []
   at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x108817: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)
 Address 0x5b7dc80 is 0 bytes inside a block of size 10 alloc'd
   at 0x4C3089F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x108802: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)

正确的方式

  • If allocated with malloc, calloc, realloc, valloc or memalign, you must deallocate with free
  • If allocated with new[], you must deallocate with delete[]
  • If allocated with new, you must deallocate with delete

Passing system call parameters with inadequate read/write permissions

当发送系统调用时,Memcheck会检测系统调用的所有参数。

  • 如果是内核从用户应用程序buffer中读取数据,Memcheck会检测:1)buffer地址是否是可寻址的,2)这个数据是否是可读的。
  • 如果是从内核向用户程序中的buffer写入数据,Memcheck会检测:1)buffer地址是否是可寻址的。

完成这个系统调用后,Memcheck更新其管理信息,以准确反映由系统调用引起的内存许可权的任何更改。
比如:

    char* arr = (char*)::malloc(10);
    ::write(STDOUT_FILENO, arr, 10);

检测就会发生错误:

 Syscall param write(buf) points to uninitialised byte(s)
    at 0x52D5154: write (write.c:27)
    by 0x1087FC: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)
  Address 0x5b7dc80 is 0 bytes inside a block of size 10 alloc'd
    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x1087E2: main (in /home/szz/Study/SystemProgram/Cpp/unitest/src/a.out)

因此程序试图向将未初始化的内存arr写入标准输出,这个未初始化的数据是不可写的。

Overlapping source and destination blocks

即目的和源地址存在重复,主要是 memcpy(), strcpy(), strncpy(), strcat()strncat()等函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值