代码之家  ›  专栏  ›  技术社区  ›  hookenz

如何有效使用Valgrind

  •  5
  • hookenz  · 技术社区  · 14 年前

    我刚开始学习使用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
    
    1 回复  |  直到 11 年前
        1
  •  15
  •   Charles Salvia    14 年前

    基本上,每个valgrind错误都显示一个堆栈跟踪。堆栈跟踪的较高部分可能对您不太有用,因为它们引用库代码。但是,这些问题最终源于代码中的问题。首先扫描堆栈跟踪的第一部分,该部分引用应用程序中的一行代码(而不是库函数)。如果检查堆栈跟踪,将看到 obbs.cpp 是应用程序中导致第一个问题的原因所在。再往上一层,你可以看到第63行 mUUID.h 最终是通过 if 语句或循环。

    “错误” Conditional jump or move depends on uninitialised value(s) “表示您有一个未初始化的变量,该变量正用于影响程序的流。在您的例子中,看起来您正在将一个未初始化的变量传递给boost library函数,而library函数正在调用处理程序类,该类在条件语句中计算未初始化的变量。这意味着你的程序表现出未定义的行为。

    导致这个问题的一个小例子是:

    int i; // uninitialized value
    if (i == 10) { /* ... do something */ }
    

    从检查第198行开始 对象.cpp 然后向上移动堆栈跟踪,直到您意识到问题所在。

    我还将添加这样的错误,如果您编译时带有所有警告,编译器有时会捕获这些错误。(例如,在gcc中,确保使用-wall标志编译)