valgrind

ある目的で, こんなテストプログラムを書いてみた.

#include <iostream>
#include <vector>

struct X
{
  std::vector<X*> children;
  X () { std::cout << "+[" << this << "]\n"; }
  ~X () {
    for( size_t i = 0; i < children.size(); ++i ){
      if( children[i] ){ delete children[i]; children[i] = 0; }
    }
    std::cout << "-[" << this << "]\n";
  }
};

int main () {
  X x;
  x.children.resize(2);
  x.children[0] = new X;
  x.children[1] = new X;
  x.children[0]->children.resize(2);
  x.children[0]->children[0] = new X;
  x.children[0]->children[1] = new X;
  return 0;
}

実行結果

$ ./a.out
+[0x7fff9877a320]
+[0x602030]
+[0x602050]
+[0x602090]
+[0x6020b0]
-[0x602090]
-[0x6020b0]
-[0x602030]
-[0x602050]
-[0x7fff9877a320]

とりあえず問題なく動くようだが, さて, 本当に大丈夫だろうか, と思い念のため valgrind を(人生で二度目に)使ってみた.

$ valgrind ./a.out
==25938== Memcheck, a memory error detector.
==25938== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==25938== Using LibVEX rev 1658, a library for dynamic binary translation.
==25938== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==25938== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framewor
k.
==25938== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==25938== For more details, rerun with: -v
==25938==
==25938== Conditional jump or move depends on uninitialised value(s)
==25938==    at 0x40151F1: (within /lib/ld-2.7.so)
==25938==    by 0x4005052: (within /lib/ld-2.7.so)
==25938==    by 0x4007BA8: (within /lib/ld-2.7.so)
==25938==    by 0x400302E: (within /lib/ld-2.7.so)
==25938==    by 0x4013C14: (within /lib/ld-2.7.so)
==25938==    by 0x4001318: (within /lib/ld-2.7.so)
==25938==    by 0x4000A67: (within /lib/ld-2.7.so)
vex amd64->IR: unhandled instruction bytes: 0x66 0x66 0x66 0x66
==25938== valgrind: Unrecognised instruction at address 0x4015A71.
==25938== Your program just tried to execute an instruction that Valgrind
==25938== did not recognise.  There are two possible reasons for this.
==25938== 1. Your program has a bug and erroneously jumped to a non-code
==25938==    location.  If you are running Memcheck and you just saw a
==25938==    warning about a bad jump, it's probably your program's fault.
==25938== 2. The instruction is legitimate but Valgrind doesn't handle it,
==25938==    i.e. it's Valgrind's fault.  If you think this is the case or
==25938==    you are not sure, please let us know and we'll try to fix it.
==25938== Either way, Valgrind will now raise a SIGILL signal which will
==25938== probably kill your program.
==25938==
==25938== Process terminating with default action of signal 4 (SIGILL)
==25938==  Illegal opcode at address 0x4015A71
==25938==    at 0x4015A71: (within /lib/ld-2.7.so)
==25938==    by 0x4003C0E: (within /lib/ld-2.7.so)
==25938==    by 0x4013C14: (within /lib/ld-2.7.so)
==25938==    by 0x4001318: (within /lib/ld-2.7.so)
==25938==    by 0x4000A67: (within /lib/ld-2.7.so)
==25938==
==25938== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==25938== malloc/free: in use at exit: 0 bytes in 0 blocks.
==25938== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==25938== For counts of detected errors, rerun with: -v
==25938== All heap blocks were freed -- no leaks are possible.
zsh: illegal hardware instruction  valgrind ./a.out

不正な命令って? なんだかおかしい.
でもこれは実は心配なくて, valgrind が新しめの命令に対応していないだけらしい. aptitude install valgrind/testing したら大丈夫になった.

《参考》
http://bbs.archlinux.org/viewtopic.php?pid=315064