Bash on Windows (Windows Subsystem for Linux) でvalgrindを動かす

Windows上でLinux(Ubuntu)のバイナリを動かすBash on Windowsが発表され(Windows Subsystem for Linuxという呼び方もされているが、用語の使い分けがよく分からない)、bash, gcc, clangといったツールがWindows上で動くようになった。

gccやclangを動かすだけなら今までもCygwinやMSYSといった環境があったが、これらの環境にはvalgrindを動かすことができないという大きな問題がある。メモリリークのチェックなら他にもいくつかツールはあるが、やはりvalgrindが優秀だと思う。

Bash on WindowsならLinuxのシステムをかなり忠実に再現していて、Ubuntuのバイナリがそのまま動いているらしい。であればvalgrindもいけるはず、ということで試してみた。

インストールはapt-get install valgrindで簡単にできる。で動かしてみたところ、

$ valgrind --leak-check=full ./a.out
--15035:0:aspacem   -1: ANON 0038000000-00383d5fff 4022272 r-x-- SmFixed d=0x000 i=421087  o=0       (0) m=0 /usr/lib/valgrind/memcheck-amd64-linux
--15035:0:aspacem  Valgrind: FATAL: aspacem assertion failed:
--15035:0:aspacem    segment_is_sane
--15035:0:aspacem    at m_aspacemgr/aspacemgr-linux.c:1502 (add_segment)
--15035:0:aspacem  Exiting now.

というエラーを吐いて終了。a.outコマンドを実行するのに失敗しているという分けでもなく、valgrind --helpだけでも落ちる。

ググってみたところ、bash on windowsのGithubによれば、valgrind-3.11.0をソースから入れれば動くらしい。

ということでやってみた。

ソースのダウンロードは公式サイトのダウンロードページから。ビルドは特に難しいことなく、configure; make; make installでできるっぽい。aptで入れたvalgrindとぶつからないよう、--prefixオプションを使おう。

$ tar xvjf valgrind-3.11.0.tar.bz2
$ cd valgrind-3.11.0
$ ./configure --prefix=/usr/local/valgrind-3.11.0
$ make -j4
$ sudo make install

これだけでビルド・インストールできたので、早速メモリリークを起こすサンプルを作って試したところ……

$ /usr/local/valgrind-3.11.0/bin/valgrind --leak-check=full ./a.out
==15064== Memcheck, a memory error detector
==15064== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==15064== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==15064== Command: ./a.out
==15064==
==15064==
==15064== HEAP SUMMARY:
==15064==     in use at exit: 1 bytes in 1 blocks
==15064==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==15064==
==15064== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==15064==    at 0x4C2B145: operator new(unsigned long) (vg_replace_malloc.c:333)
==15064==    by 0x40071E: main (main.cpp:9)
==15064==
==15064== LEAK SUMMARY:
==15064==    definitely lost: 1 bytes in 1 blocks
==15064==    indirectly lost: 0 bytes in 0 blocks
==15064==      possibly lost: 0 bytes in 0 blocks
==15064==    still reachable: 0 bytes in 0 blocks
==15064==         suppressed: 0 bytes in 0 blocks
==15064==
==15064== For counts of detected and suppressed errors, rerun with: -v
==15064== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)

できた!

これでBash on WindowsでのC/C++の開発も結構いけるんじゃないだろうか。

ちなみに、valgrindのビルドにかかった時間(make -j4の時間)は、Windows 10 (64bit)、Core i7-2600 (3.4GHz)、RAM 16GB、SSDの環境で約47秒。また、このPCのVMwareの仮想環境に入れたUbuntu-16.04 (64ビット)の環境では、make -j4で1分12秒かかった。それぞれ1回しかやっていないので正確な計測ではないが、Bash on WindowsのC言語開発環境のパフォーマンスはVMware上のLinuxと比べてもそれほど大差はないのかもしれない。