没有合适的资源?快使用搜索试试~ 我知道了~
首页Valgrind 3.8.0 快速入门与用户手册指南
Valgrind 3.8.0 快速入门与用户手册指南
需积分: 10 12 下载量 189 浏览量
更新于2024-07-26
收藏 1.24MB PDF 举报
Valgrind 是一个强大的内存调试和性能分析工具,适用于 C、C++ 和 Fortran 程序。这个文档是 Valgrind 的 3.8.0 版本的手册,发布于 2012 年 8 月 10日,由 Valgrind 开发者享有 GNU Free Documentation License 的版权。该许可证允许用户自由复制、分发和修改文档,但有一些特定的条款,如不包含不变节、无封面文本和无背面文本。
文档结构分为六个部分:
1. **Valgrind Quick Start Guide**:这是一份快速入门指南,为初学者提供了快速上手 Valgrind 的步骤,适合想要了解如何使用工具进行基本内存检查和性能优化的新用户。
2. **Valgrind User Manual**:这是 Valgrind 的详尽用户手册,提供了全面的技术细节和深入的教程,包括 Memcheck、Cachegrind、Helgrind、Callgrind 等工具的详细介绍,以及如何配置和利用它们来识别程序中的内存泄漏、错误访问和缓存失效等问题。
3. **Valgrind FAQ**:解答了关于 Valgrind 常见问题的集合,对于遇到常见问题的用户来说是个宝库。
4. **Valgrind Technical Documentation**:涵盖了更专业的技术文档,可能包括开发人员需要的高级用法、API 参考、以及工具内部的工作原理。
5. **Valgrind Distribution Documents**:包含与 Valgrind 发行版相关的文档,可能涉及安装、更新、打包和打包器的信息。
6. **GNULicenses**:列出了 Valgrind 使用的各种 GNU 许可证,确保用户了解其软件的授权情况。
为了充分利用 Valgrind,读者应首先阅读 Quick Start Guide,熟悉基本操作和工具。对于高级用户和开发者,User Manual 是深入学习和解决复杂问题的核心资源。在整个过程中,Valgrind 提供了一套完整的工具链,用于诊断代码质量、内存效率和潜在的并行性能问题,是任何致力于编写健壮、高效代码的开发者的重要辅助工具。
Using and understanding the Valgrind core
Different error-checking tools report different kinds of errors. The suppression mechanism therefore allows you to say
which tool or tool(s) each suppression applies to.
2.2. Getting started
First off, consider whether it might be beneficial to recompile your application and supporting libraries with debugging
info enabled (the -g option). Without debugging info, the best Valgrind tools will be able to do is guess which function
a particular piece of code belongs to, which makes both error messages and profiling output nearly useless. With -g,
you’ll get messages which point directly to the relevant source code lines.
Another option you might like to consider, if you are working with C++, is -fno-inline. That makes it easier to
see the function-call chain, which can help reduce confusion when navigating around large C++ apps. For example,
debugging OpenOffice.org with Memcheck is a bit easier when using this option. You don’t have to do this, but doing
so helps Valgrind produce more accurate and less confusing error reports. Chances are you’re set up like this already,
if you intended to debug your program with GNU GDB, or some other debugger.
If you are planning to use Memcheck: On rare occasions, compiler optimisations (at -O2 and above, and sometimes
-O1) have been observed to generate code which fools Memcheck into wrongly reporting uninitialised value errors,
or missing uninitialised value errors. We have looked in detail into fixing this, and unfortunately the result is that
doing so would give a further significant slowdown in what is already a slow tool. So the best solution is to turn off
optimisation altogether. Since this often makes things unmanageably slow, a reasonable compromise is to use -O.
This gets you the majority of the benefits of higher optimisation levels whilst keeping relatively small the chances of
false positives or false negatives from Memcheck. Also, you should compile your code with -Wall because it can
identify some or all of the problems that Valgrind can miss at the higher optimisation levels. (Using -Wall is also a
good idea in general.) All other tools (as far as we know) are unaffected by optimisation level, and for profiling tools
like Cachegrind it is better to compile your program at its normal optimisation level.
Valgrind understands both the older "stabs" debugging format, used by GCC versions prior to 3.1, and the newer
DWARF2/3/4 formats used by GCC 3.1 and later. We continue to develop our debug-info readers, although the
majority of effort will naturally enough go into the newer DWARF readers.
When you’re ready to roll, run Valgrind as described above. Note that you should run the real (machine-code)
executable here. If your application is started by, for example, a shell or Perl script, you’ll need to modify it to
invoke Valgrind on the real executables. Running such scripts directly under Valgrind will result in you getting error
reports pertaining to /bin/sh, /usr/bin/perl, or whatever interpreter you’re using. This may not be what you
want and can be confusing. You can force the issue by giving the option --trace-children=yes, but confusion
is still likely.
2.3. The Commentary
Valgrind tools write a commentary, a stream of text, detailing error reports and other significant events. All lines in
the commentary have following form:
==12345== some-message-from-Valgrind
The 12345 is the process ID. This scheme makes it easy to distinguish program output from Valgrind commentary,
and also easy to differentiate commentaries from different processes which have become merged together, for whatever
reason.
By default, Valgrind tools write only essential messages to the commentary, so as to avoid flooding you with
information of secondary importance. If you want more information about what is happening, re-run, passing the -v
option to Valgrind. A second -v gives yet more detail.
4
Using and understanding the Valgrind core
You can direct the commentary to three different places:
1. The default: send it to a file descriptor, which is by default 2 (stderr). So, if you give the core no options, it will
write commentary to the standard error stream. If you want to send it to some other file descriptor, for example
number 9, you can specify --log-fd=9.
This is the simplest and most common arrangement, but can cause problems when Valgrinding entire trees of
processes which expect specific file descriptors, particularly stdin/stdout/stderr, to be available for their own use.
2. A less intrusive option is to write the commentary to a file, which you specify by --log-file=filename.
There are special format specifiers that can be used to use a process ID or an environment variable name in the log
file name. These are useful/necessary if your program invokes multiple processes (especially for MPI programs).
See the basic options section for more details.
3. The least intrusive option is to send the commentary to a network socket. The socket is specified as an IP address
and port number pair, like this: --log-socket=192.168.0.1:12345 if you want to send the output to host
IP 192.168.0.1 port 12345 (note: we have no idea if 12345 is a port of pre-existing significance). You can also omit
the port number: --log-socket=192.168.0.1, in which case a default port of 1500 is used. This default is
defined by the constant VG_CLO_DEFAULT_LOGPORT in the sources.
Note, unfortunately, that you have to use an IP address here, rather than a hostname.
Writing to a network socket is pointless if you don’t have something listening at the other end. We provide a simple
listener program, valgrind-listener, which accepts connections on the specified port and copies whatever
it is sent to stdout. Probably someone will tell us this is a horrible security risk. It seems likely that people will
write more sophisticated listeners in the fullness of time.
valgrind-listener can accept simultaneous connections from up to 50 Valgrinded processes. In front of
each line of output it prints the current number of active connections in round brackets.
valgrind-listener accepts two command-line options:
• -e or --exit-at-zero: when the number of connected processes falls back to zero, exit. Without this, it
will run forever, that is, until you send it Control-C.
• portnumber: changes the port it listens on from the default (1500). The specified port must be in the range
1024 to 65535. The same restriction applies to port numbers specified by a --log-socket to Valgrind itself.
If a Valgrinded process fails to connect to a listener, for whatever reason (the listener isn’t running, invalid or
unreachable host or port, etc), Valgrind switches back to writing the commentary to stderr. The same goes for
any process which loses an established connection to a listener. In other words, killing the listener doesn’t kill the
processes sending data to it.
5
Using and understanding the Valgrind core
Here is an important point about the relationship between the commentary and profiling output from tools. The
commentary contains a mix of messages from the Valgrind core and the selected tool. If the tool reports errors, it will
report them to the commentary. However, if the tool does profiling, the profile data will be written to a file of some
kind, depending on the tool, and independent of what --log-
*
options are in force. The commentary is intended
to be a low-bandwidth, human-readable channel. Profiling data, on the other hand, is usually voluminous and not
meaningful without further processing, which is why we have chosen this arrangement.
2.4. Reporting of errors
When an error-checking tool detects something bad happening in the program, an error message is written to the
commentary. Here’s an example from Memcheck:
==25832== Invalid read of size 4
==25832== at 0x8048724: BandMatrix::ReSize(int, int, int) (bogon.cpp:45)
==25832== by 0x80487AF: main (bogon.cpp:66)
==25832== Address 0xBFFFF74C is not stack’d, malloc’d or free’d
This message says that the program did an illegal 4-byte read of address 0xBFFFF74C, which, as far as Memcheck
can tell, is not a valid stack address, nor corresponds to any current heap blocks or recently freed heap blocks. The
read is happening at line 45 of bogon.cpp, called from line 66 of the same file, etc. For errors associated with
an identified (current or freed) heap block, for example reading freed memory, Valgrind reports not only the location
where the error happened, but also where the associated heap block was allocated/freed.
Valgrind remembers all error reports. When an error is detected, it is compared against old reports, to see if it is a
duplicate. If so, the error is noted, but no further commentary is emitted. This avoids you being swamped with
bazillions of duplicate error reports.
If you want to know how many times each error occurred, run with the -v option. When execution finishes, all the
reports are printed out, along with, and sorted by, their occurrence counts. This makes it easy to see which errors have
occurred most frequently.
Errors are reported before the associated operation actually happens. For example, if you’re using Memcheck and
your program attempts to read from address zero, Memcheck will emit a message to this effect, and your program will
then likely die with a segmentation fault.
In general, you should try and fix errors in the order that they are reported. Not doing so can be confusing. For
example, a program which copies uninitialised values to several memory locations, and later uses them, will generate
several error messages, when run on Memcheck. The first such error message may well give the most direct clue to
the root cause of the problem.
The process of detecting duplicate errors is quite an expensive one and can become a significant performance overhead
if your program generates huge quantities of errors. To avoid serious problems, Valgrind will simply stop collecting
errors after 1,000 different errors have been seen, or 10,000,000 errors in total have been seen. In this situation you
might as well stop your program and fix it, because Valgrind won’t tell you anything else useful after this. Note that
the 1,000/10,000,000 limits apply after suppressed errors are removed. These limits are defined in m_errormgr.c
and can be increased if necessary.
To avoid this cutoff you can use the --error-limit=no option. Then Valgrind will always show errors, regardless
of how many there are. Use this option carefully, since it may have a bad effect on performance.
2.5. Suppressing errors
6
Using and understanding the Valgrind core
The error-checking tools detect numerous problems in the system libraries, such as the C library, which come pre-
installed with your OS. You can’t easily fix these, but you don’t want to see these errors (and yes, there are many!)
So Valgrind reads a list of errors to suppress at startup. A default suppression file is created by the ./configure
script when the system is built.
You can modify and add to the suppressions file at your leisure, or, better, write your own. Multiple suppression files
are allowed. This is useful if part of your project contains errors you can’t or don’t want to fix, yet you don’t want to
continuously be reminded of them.
Note: By far the easiest way to add suppressions is to use the --gen-suppressions=yes option described in
Core Command-line Options. This generates suppressions automatically. For best results, though, you may want to
edit the output of --gen-suppressions=yes by hand, in which case it would be advisable to read through this
section.
Each error to be suppressed is described very specifically, to minimise the possibility that a suppression-directive
inadvertently suppresses a bunch of similar errors which you did want to see. The suppression mechanism is designed
to allow precise yet flexible specification of errors to suppress.
If you use the -v option, at the end of execution, Valgrind prints out one line for each used suppression, giving its name
and the number of times it got used. Here’s the suppressions used by a run of valgrind --tool=memcheck
ls -l:
--27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getgrgid_r
--27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getpwuid_r
--27579-- supp: 6 strrchr/_dl_map_object_from_fd/_dl_map_object
Multiple suppressions files are allowed. By default, Valgrind uses $PREFIX/lib/valgrind/default.supp.
You can ask to add suppressions from another file, by specifying --suppressions=/path/to/file.supp.
If you want to understand more about suppressions, look at an existing suppressions file whilst reading the following
documentation. The file glibc-2.3.supp, in the source distribution, provides some good examples.
Each suppression has the following components:
• First line: its name. This merely gives a handy name to the suppression, by which it is referred to in the summary
of used suppressions printed out when a program finishes. It’s not important what the name is; any identifying
string will do.
• Second line: name of the tool(s) that the suppression is for (if more than one, comma-separated), and the name of
the suppression itself, separated by a colon (n.b.: no spaces are allowed), eg:
tool_name1,tool_name2:suppression_name
Recall that Valgrind is a modular system, in which different instrumentation tools can observe your program whilst it
is running. Since different tools detect different kinds of errors, it is necessary to say which tool(s) the suppression
is meaningful to.
Tools will complain, at startup, if a tool does not understand any suppression directed to it. Tools ignore
suppressions which are not directed to them. As a result, it is quite practical to put suppressions for all tools
into the same suppression file.
7
Using and understanding the Valgrind core
• Next line: a small number of suppression types have extra information after the second line (eg. the Param
suppression for Memcheck)
• Remaining lines: This is the calling context for the error -- the chain of function calls that led to it. There can be
up to 24 of these lines.
Locations may be names of either shared objects or functions. They begin obj: and fun: respectively. Function
and object names to match against may use the wildcard characters
*
and ?.
Important note: C++ function names must be mangled. If you are writing suppressions by hand, use the
--demangle=no option to get the mangled names in your error messages. An example of a mangled C++ name
is _ZN9QListView4showEv. This is the form that the GNU C++ compiler uses internally, and the form that
must be used in suppression files. The equivalent demangled name, QListView::show(), is what you see at
the C++ source code level.
A location line may also be simply "..." (three dots). This is a frame-level wildcard, which matches zero or more
frames. Frame level wildcards are useful because they make it easy to ignore varying numbers of uninteresting
frames in between frames of interest. That is often important when writing suppressions which are intended to be
robust against variations in the amount of function inlining done by compilers.
• Finally, the entire suppression must be between curly braces. Each brace must be the first character on its own line.
A suppression only suppresses an error when the error matches all the details in the suppression. Here’s an example:
{
__gconv_transform_ascii_internal/__mbrtowc/mbtowc
Memcheck:Value4
fun:__gconv_transform_ascii_internal
fun:__mbr
*
toc
fun:mbtowc
}
What it means is: for Memcheck only, suppress a use-of-uninitialised-value error, when the data size
is 4, when it occurs in the function __gconv_transform_ascii_internal, when that is called
from any function of name matching __mbr
*
toc, when that is called from mbtowc. It doesn’t ap-
ply under any other circumstances. The string by which this suppression is identified to the user is
__gconv_transform_ascii_internal/__mbrtowc/mbtowc.
(See Writing suppression files for more details on the specifics of Memcheck’s suppression kinds.)
Another example, again for the Memcheck tool:
{
libX11.so.6.2/libX11.so.6.2/libXaw.so.7.0
Memcheck:Value4
obj:/usr/X11R6/lib/libX11.so.6.2
obj:/usr/X11R6/lib/libX11.so.6.2
obj:/usr/X11R6/lib/libXaw.so.7.0
}
This suppresses any size 4 uninitialised-value error which occurs anywhere in libX11.so.6.2, when called from
anywhere in the same library, when called from anywhere in libXaw.so.7.0. The inexact specification of
8
剩余318页未读,继续阅读
2016-01-18 上传
liuxuejiang158
- 粉丝: 545
- 资源: 112
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C语言数组操作:高度检查器编程实践
- 基于Swift开发的嘉定单车LBS iOS应用项目解析
- 钗头凤声乐表演的二度创作分析报告
- 分布式数据库特训营全套教程资料
- JavaScript开发者Robert Bindar的博客平台
- MATLAB投影寻踪代码教程及文件解压缩指南
- HTML5拖放实现的RPSLS游戏教程
- HT://Dig引擎接口,Ampoliros开源模块应用
- 全面探测服务器性能与PHP环境的iprober PHP探针v0.024
- 新版提醒应用v2:基于MongoDB的数据存储
- 《我的世界》东方大陆1.12.2材质包深度体验
- Hypercore Promisifier: JavaScript中的回调转换为Promise包装器
- 探索开源项目Artifice:Slyme脚本与技巧游戏
- Matlab机器人学习代码解析与笔记分享
- 查尔默斯大学计算物理作业HP2解析
- GitHub问题管理新工具:GIRA-crx插件介绍
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功