如何有效使用 valgrind
我刚刚开始学习使用 valgrind 和 --tool=memcheck
但我遇到的麻烦实际上是发现问题。
例如,
这样的问题之一就是这样。
==12561== Conditional jump or move depends on uninitialised value(s)
==12561== at 0x425779: Server::HandleReceiveFrom(boost::system::error_code const&, unsigned long) (mUUID.h:63)
==12561== by 0x428EC4: boost::asio::detail::reactive_socket_recvfrom_op<boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint<boost::asio::ip::udp>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, Server, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<Server*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code, unsigned long) (mem_fn_template.hpp:280)
==12561== by 0x42E589: boost::asio::detail::task_io_service::run(boost::system::error_code&) (task_io_service_operation.hpp:35)
==12561== by 0x42720C: Server::Run() (io_service.ipp:57)
==12561== by 0x42FB00: main (obbs.cpp:198)
另一个是
== Use of uninitialised value of size 8
==12561== at 0x5E56091: _itoa_word (_itoa.c:196)
==12561== by 0x5E573D8: vfprintf (vfprintf.c:1613)
==12561== by 0x5F0EA6F: __vsnprintf_chk (vsnprintf_chk.c:65)
我正在寻找一些关于如何最有效地跟踪这些类型的问题的提示。 (条件跳转和未初始化的值。)
编辑
这有什么值得担心的吗?似乎随着选项 --run-libc-freeres=no
消失。 这是否意味着我的 C 库有问题?
==14754== Invalid free() / delete / delete[]
==14754== at 0x4C27D71: free (vg_replace_malloc.c:366)
==14754== by 0x5F43A0A: free_mem (in /lib/libc-2.12.1.so)
==14754== by 0x5F435A1: __libc_freeres (in /lib/libc-2.12.1.so)
==14754== by 0x4A2366B: _vgnU_freeres (vg_preloaded.c:62)
==14754== by 0x5E4A4A4: exit (exit.c:93)
==14754== by 0x5E2FD94: (below main) (libc-start.c:258)
==14754== Address 0x4046bb8 is not stack'd, malloc'd or (recently) free'd
I've just started learning to use valgrind and the --tool=memcheck
But what I am having trouble with is actually finding the problems.
e.g.
One such problem is this.
==12561== Conditional jump or move depends on uninitialised value(s)
==12561== at 0x425779: Server::HandleReceiveFrom(boost::system::error_code const&, unsigned long) (mUUID.h:63)
==12561== by 0x428EC4: boost::asio::detail::reactive_socket_recvfrom_op<boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint<boost::asio::ip::udp>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, Server, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<Server*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code, unsigned long) (mem_fn_template.hpp:280)
==12561== by 0x42E589: boost::asio::detail::task_io_service::run(boost::system::error_code&) (task_io_service_operation.hpp:35)
==12561== by 0x42720C: Server::Run() (io_service.ipp:57)
==12561== by 0x42FB00: main (obbs.cpp:198)
and another is this
== Use of uninitialised value of size 8
==12561== at 0x5E56091: _itoa_word (_itoa.c:196)
==12561== by 0x5E573D8: vfprintf (vfprintf.c:1613)
==12561== by 0x5F0EA6F: __vsnprintf_chk (vsnprintf_chk.c:65)
I'm after some hints on how to most effectively trace these types of problems. (Conditional jumps and uninitialised values.)
EDIT
Is this anything to worry about? Seems to disappear with the option --run-libc-freeres=no
.
Does that mean I have a buggy C library?
==14754== Invalid free() / delete / delete[]
==14754== at 0x4C27D71: free (vg_replace_malloc.c:366)
==14754== by 0x5F43A0A: free_mem (in /lib/libc-2.12.1.so)
==14754== by 0x5F435A1: __libc_freeres (in /lib/libc-2.12.1.so)
==14754== by 0x4A2366B: _vgnU_freeres (vg_preloaded.c:62)
==14754== by 0x5E4A4A4: exit (exit.c:93)
==14754== by 0x5E2FD94: (below main) (libc-start.c:258)
==14754== Address 0x4046bb8 is not stack'd, malloc'd or (recently) free'd
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本上,每个 Valgrind 错误都会显示堆栈跟踪。堆栈跟踪的较高部分可能对您不太有用,因为它们引用了库代码。然而,最终这些问题源于代码中的问题。首先扫描堆栈跟踪的第一部分,它引用应用程序中的一行代码(而不是库函数)。如果检查堆栈跟踪,您将看到 obbs 的第 198 行。 cpp 是应用程序中导致第一个问题的原因的点。在堆栈的更上方,您可以看到 mUUID.h 的第 63 行最终是通过 if 语句或循环评估未初始化变量的位置。
错误“
条件跳转或移动取决于未初始化的值
”意味着您有一个未初始化的变量被用来影响程序的流程。在您的情况下,您似乎正在将未初始化的变量传递给 Boost 库函数,并且该库函数正在调用您的处理程序类,该处理程序类在条件语句中评估未初始化的变量。这意味着您的程序表现出未定义的行为。一个可能导致此问题的简单示例如下所示:
首先检查 obbs.cpp 的第 198 行,然后向上移动堆栈跟踪,直到意识到问题为止。
我还要补充一点,如果您在编译时带有所有警告,那么编译器有时会捕获这样的错误。 (例如,在 GCC 中,请确保使用 -Wall 标志进行编译)
Basically, each Valgrind error displays a stack trace. The higher portions of the stack trace might not be very useful to you, since they refer to library code. However, ultimately these problems stem from issues in your code. Start by scanning for the first part of the stack trace which refers to a line of code in your application (as opposed to a library function.) If you examine the stack trace, you'll see that line 198 of
obbs.cpp
is the point in your application leading to the cause of your first problem. Further up the stack, you can see that line 63 ofmUUID.h
is ultimately where the uninitialized variable is evaluated, either via anif
statement, or a loop.The error "
Conditional jump or move depends on uninitialised value(s)
" means you have an uninitialized variable that is being used to affect the flow of your program. In your case, it looks like you're passing an uninitialized variable to a Boost library function, and the library function is calling your handler class which evaluates the uninitialized variable in a conditional statement. This means your program is exhibiting undefined behavior.A trivial example that would cause this problem would be something like:
Start by checking line 198 of
obbs.cpp
and move up the stack trace until you realize the problem.I'll also add that errors like this can sometimes be caught by the compiler, if you compile with all warnings. (In GCC, for example, make sure you compile with the -Wall flag)