我可以让valgrind告诉我_哪个_值未初始化吗?

Joh*_*rry 4 c++ valgrind initialization

valgrind按以下方式运行一些代码:

valgrind --tool=memcheck --leak-check=full --track-origins=yes ./test
Run Code Online (Sandbox Code Playgroud)

它返回以下错误:

==24860== Conditional jump or move depends on uninitialised value(s)
==24860==    at 0x4081AF: GG::fl(M const&, M const&) const (po.cpp:71)
==24860==    by 0x405CDB: MO::fle(M const&, M const&) const (m.cpp:708)
==24860==    by 0x404310: M::operator>=(M const&) const (m.cpp:384)
==24860==    by 0x404336: M::operator<(M const&) const (m.cpp:386)
==24860==    by 0x4021FD: main (test.cpp:62)
==24860==  Uninitialised value was created by a heap allocation
==24860==    at 0x4C2EBAB: malloc (vg_replace_malloc.c:299)
==24860==    by 0x40653F: GODA<unsigned int>::allocate_new_block() (goda.hpp:82)
==24860==    by 0x406182: GODA<unsigned int>::GODA(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (goda.hpp:103)
==24860==    by 0x402A0E: M::init(unsigned long) (m.cpp:63)
==24860==    by 0x403831: M::M(std::initializer_list<unsigned int>, MO const*) (m.cpp:248)
==24860==    by 0x401B56: main (test.cpp:31)
Run Code Online (Sandbox Code Playgroud)

因此第71行有错误。好的,不错。以下是通往第71 po.cpp行的行(最后71 行):

DEG_TYPE dtk = t.ord_deg();
DEG_TYPE duk = u.ord_deg();
bool searching = dtk == duk;
NVAR_TYPE n = t.nv();
NVAR_TYPE k = 0;
for (/* */; searching and k < n; ++k) { // this is line 71
Run Code Online (Sandbox Code Playgroud)

OK,那么第71行的哪个值未初始化?

  • 当然不是k;
  • 我手动检查了(=“ stepping through gdb”)t的构造函数初始化了返回的值t.nv(),所以肯定不会n(实际上n设置为6,即正确的值);
  • searching由下式确定dtkduk的,但我还手动检查出t的和u的构造初始化由返回的值.ord_deg()(实际上两者dtkduk被设置为3,正确的值)。

我在这里完全不知所措。是否有一些选项可以告诉valgrind您它认为尚未初始化的精确值

更新资料

在回答一个问题时,这是第61行test.cpp

M s { 1, 0, 5, 2, 0 };
Run Code Online (Sandbox Code Playgroud)

因此,它使用初始化列表进行构造。这是构造函数:

M::M(
    initializer_list<EXP_TYPE> p, const MO * ord
) {
  common_init(ord);
  init_e(p.size());
  NVAR_TYPE i = 0;
  last = 0;
  for (
       auto pi = p.begin();
       pi != p.end();
       ++pi
  ) {
    if (*pi != 0) {
      e[last] = i;
      e[last + 1] = *pi;
      last += 2;
    }
    ++i;
  }
  ord->set_data(*this);
}
Run Code Online (Sandbox Code Playgroud)

这是类中的数据,添加注释以显示其初始化位置:

NVAR_TYPE n;    // init_e()
EXP_TYPE * e;   // common_init()
NVAR_TYPE last; // common_init()
DEG_TYPE od;    // common_init(), revised in ord->set_data()
const MO * o;   // common_init()
MOD * o_data;   // common_init(), revised in ord->set_data()
Run Code Online (Sandbox Code Playgroud)

ks1*_*322 7

是否有一些选项可以告诉valgrind报告它认为尚未初始化的精确值?

最好的办法是使用--track-origins=yes(您已经在使用此选项)。Valgrind将仅告诉您未初始化值的大概位置(以Valgrind表示),而不告诉您确切的变量名称。见Valgrind的手册--track-origins

设置为yes时,Memcheck会跟踪所有未初始化值的来源。然后,当报告未初始化的值错误时,Memcheck将尝试显示值的来源。源可以是以下四个位置之一:堆块,堆栈分配,客户端请求或其他各种源(例如,对brk的调用)。

对于源自堆块的未初始化值,Memcheck将显示该块的分配位置。对于源自堆栈分配的未初始化值,Memcheck可以告诉您哪个函数分配了该值,但仅此而已-通常,它会向您显示该函数的左括号的源位置。因此,您应该仔细检查函数的所有局部变量是否已正确初始化。


phd*_*phd 5

您可以使用 gdb+vgdb+valgrind 在 valgrind 下调试您的程序。

然后,当 valgrind 因上述错误而停止时,您可以使用监视器请求“xb”或“get_vbits”来检查您感兴趣的变量的定义,方法是询问变量的地址,然后检查 vbit 的大小变量的。

例如:

p &searching
=> 0xabcdef
monitor xb 0xabcdef 1
=> will show you the value of searching and the related vbits.
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅“使用 Valgrind gdbserver 和 GDB 调试程序” http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver 和“Memcheck 监视器命令” http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands