valgrind 简单使用 - yanbin's Blog
valgrind 简单使用
yanbin
posted @ 2015年3月16日 00:03
in Programming
, 1749 阅读
valgrind 是一款 memorycheck 工具,用于 c/c++ 程序的内存检查/调试。
0. 为了使用 valgrind 编译程序时要使用 gcc 的 -g 编译选项,链接libc 的 debug 版本,
自动链接,但是要求有, 如果没有 valgrind 不能正常启动内存检查.
程序用到的其他 C 库也要有 debug 版本的。
也可以使用 gcc 的 -O0 编译选项。据说使用了更好。(大写 O, 数字 0)
自动链接,但是要求有, 如果没有 valgrind 不能正常启动内存检查.
程序用到的其他 C 库也要有 debug 版本的。
也可以使用 gcc 的 -O0 编译选项。据说使用了更好。(大写 O, 数字 0)
-g 是表示编译出的二进制代码中包含调试符号
-O0 是 gcc 的默认选项。可能一些低版本的 gcc 需要加上这个选项。
1. Memorycheck 是 valgrind 的默认工具,--leak-check 选项可以打开 valgrind 详细的 memory leak 探测工具。
$ gcc -O0 -g example.c -o example
$ valgrind --leack-check=yes ./example arg1 arg2
$ gcc -O0 -g example.c -o example
$ valgrind --leack-check=yes ./example arg1 arg2
2. valgrind 的输出。
下面是一个正常分配并正常释放内存的程序用 valgrind 调试的输出:
下面是一个正常分配并正常释放内存的程序用 valgrind 调试的输出:
# 733 是 process id, 无关紧要;
==733== Memcheck, a memory error detector
==733== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==733== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright
info
# 以下是重要信息;
==733== Command: ./mkdir_t 1/2/3/4
==733==
# 这里可能会有程序的 stdout/stderr 输出;
==733==
# 内存使用状况的汇总;
==733== HEAP SUMMARY:
==733== in use at exit: 0 bytes in 0 blocks
==733== total heap usage: 3 allocs, 3 frees, 18 bytes allocated
==733==
==733== All heap blocks were freed -- no leaks are possible
==733==
# 错误信息汇总;(这里没有错误)
==733== For counts of detected and suppressed errors, rerun with: -v
==733== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
下面是一个越界使用了动态分配的内存, 没有释放动态分配内存的程序的输出;
程序名字是 example, 程序文件名后面的数字说明了 memory allocated 之类的操作的
代码在文件中的位置, 或者说哪里有 memory allocated.
==733== Memcheck, a memory error detector
==733== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==733== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright
info
# 以下是重要信息;
==733== Command: ./mkdir_t 1/2/3/4
==733==
# 这里可能会有程序的 stdout/stderr 输出;
==733==
# 内存使用状况的汇总;
==733== HEAP SUMMARY:
==733== in use at exit: 0 bytes in 0 blocks
==733== total heap usage: 3 allocs, 3 frees, 18 bytes allocated
==733==
==733== All heap blocks were freed -- no leaks are possible
==733==
# 错误信息汇总;(这里没有错误)
==733== For counts of detected and suppressed errors, rerun with: -v
==733== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
下面是一个越界使用了动态分配的内存, 没有释放动态分配内存的程序的输出;
程序名字是 example, 程序文件名后面的数字说明了 memory allocated 之类的操作的
代码在文件中的位置, 或者说哪里有 memory allocated.
# Invalid write 指示了 memory overrun;
==1058== Invalid write of size 4
# 这里是堆栈跟踪(stack tracking), stack tracking 从下到上读比较容易;
==1058== at 0x40054A: func (example.c:15)
==1058== by 0x400524: main (example.c:8)
==1058== Address 0x51bc068 is 0 bytes after a block of size 40 alloc'd
==1058== Invalid write of size 4
# 这里是堆栈跟踪(stack tracking), stack tracking 从下到上读比较容易;
==1058== at 0x40054A: func (example.c:15)
==1058== by 0x400524: main (example.c:8)
==1058== Address 0x51bc068 is 0 bytes after a block of size 40 alloc'd
# 这里也是 stack tracking 信息,比上面的更深了一层,
# 已经到了 malloc 是内存分配的情况;
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14) # 后面的数字指示了代码所在行
==1058== by 0x400524: main (example.c:8)
==1058==
==1058==
# 内存(HEAP),使用汇总;
==1058== HEAP SUMMARY:
==1058== in use at exit: 40 bytes in 1 blocks
# N allocs, N frees 才正常, 40 bytes allocated 指示分配了多少字节内存;
==1058== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==1058==
# definitely lost 指示了内存泄漏(memory leak);
==1058== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14)
==1058== by 0x400524: main (example.c:8)
==1058==
# memory leak 汇总;
# definitely, indirectly, possibly 是三种 memory leadk 方式.
==1058== LEAK SUMMARY:
==1058== definitely lost: 40 bytes in 1 blocks # 明确地
==1058== indirectly lost: 0 bytes in 0 blocks # 间接地
==1058== possibly lost: 0 bytes in 0 blocks # 可能性很大地
==1058== still reachable: 0 bytes in 0 blocks
==1058== suppressed: 0 bytes in 0 blocks
==1058==
# 错误信息汇总
==1058== For counts of detected and suppressed errors, rerun with: -v
==1058== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
# 已经到了 malloc 是内存分配的情况;
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14) # 后面的数字指示了代码所在行
==1058== by 0x400524: main (example.c:8)
==1058==
==1058==
# 内存(HEAP),使用汇总;
==1058== HEAP SUMMARY:
==1058== in use at exit: 40 bytes in 1 blocks
# N allocs, N frees 才正常, 40 bytes allocated 指示分配了多少字节内存;
==1058== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==1058==
# definitely lost 指示了内存泄漏(memory leak);
==1058== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14)
==1058== by 0x400524: main (example.c:8)
==1058==
# memory leak 汇总;
# definitely, indirectly, possibly 是三种 memory leadk 方式.
==1058== LEAK SUMMARY:
==1058== definitely lost: 40 bytes in 1 blocks # 明确地
==1058== indirectly lost: 0 bytes in 0 blocks # 间接地
==1058== possibly lost: 0 bytes in 0 blocks # 可能性很大地
==1058== still reachable: 0 bytes in 0 blocks
==1058== suppressed: 0 bytes in 0 blocks
==1058==
# 错误信息汇总
==1058== For counts of detected and suppressed errors, rerun with: -v
==1058== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
3. If the stack trace is not big enough, use the --num-callers option to
make it bigger.
make it bigger.
4. valgrind 也报告"使用了未初始化变量错误(uninitialished value)"的情况。
使用 --track-origins=yes 可以看到有关于此的更多的扩展信息,
但是这样也会让程序变得更慢.
使用 --track-origins=yes 可以看到有关于此的更多的扩展信息,
但是这样也会让程序变得更慢.
5. Memcheck cannot detect every memory error your program has.
For example, it can't detect out-of-range reads or writes to arrays
that are allocated statically or on the stack.
But it should detect many errors that could crash your program
(eg. cause a segmentation fault).
For example, it can't detect out-of-range reads or writes to arrays
that are allocated statically or on the stack.
But it should detect many errors that could crash your program
(eg. cause a segmentation fault).
6. 使用 valgrind 调试使用了 GLib 的程序需要加一些 flag.
比如让 GLib 使用 std malloc.
2019年2月13日 17:19
The information above is very good to me, thanks for sharing!
2022年8月25日 15:52
You may quickly check the PNR live status of your rail ticket. All you need to do to check the status of an Indian Railways PNR is input your PNR number and click the button. Your live PNR status will be shown in a new window that will open. pnr status with name The ability to check IRCTC PNR status online by entering the passenger's name or not is a common point of misunderstanding among users. You cannot check the IRCTC PNR status with a name, though, as each passenger's personal information is kept private.
2022年12月19日 15:39
With the help of the Unicode character encoding standard, text may be shown consistently on a variety of systems and devices. Unicode objects are represented as strings in Python. In Python, regexes behave the same way with Unicode strings as they do with other kinds of strings. However, there are a cbd oil for sleep few considerations to make while using Unicode regexes, advises real estate consultant Orlando.
2023年1月09日 13:10
Valgrind is a memory debugging tool that is simple to use. It can be used to buy cheap diamonds online find memory leaks and errors. Valgrind can be run on any Linux system and can be used to debug programs written in any language.