Valgrindでのメモリリークチェックがおかしい件
Category: devel
概要
プログラム開発時に有用な Valgrind というツールがある。 Valgrindは色々なツールを提供してくれる。 この記事を書いた時点では以下のように書かれていて、6つのツールが提供されているとのこと。
The Valgrind distribution currently includes six production-quality tools: a memory error detector, two thread error detectors, a cache and branch-prediction profiler, a call-graph generating cache and branch-prediction profiler, and a heap profiler.
今回はこの中でもメモリチェックツールのお話。 Linux上でpthreadを使用している場合に常にメモリリークとなってしまう件。
環境は以下。 Vagrantで作成したdebian sid。
% uname -a
Linux debian 4.2.0-1-amd64 #1 SMP Debian 4.2.6-1 (2015-11-10) x86_64 GNU/Linux
% valgrind --version
valgrind-3.11.0
再現手順
メモリリークしないコード test.c
を用意する。
pthread_create
して pthread_join
するだけの簡単なお仕事。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *test(void *arg)
{
sleep(1);
pthread_exit(NULL);
return NULL;
}
int main(void)
{
pthread_t th;
printf("%d\n", pthread_create(&th, NULL, test, NULL));
printf("%d\n", pthread_join(th, NULL));
sleep(1);
return(0);
}
スレッドとして起動する関数 test
ではちょっと待ってから pthread_exit
するだけ。
起動元では pthread_join
してあげる。
これでスレッド用の資源が回収されるのでメモリリークはない。はずなのだが・・・。
このプログラムをコンパイルして、valgrindを実行してみる。
% gcc -Wall -g -lpthread -otest test.c
% valgrind --tool=memcheck \
--leak-check=yes \
--leak-resolution=high \
--num-callers=40 \
--undef-value-errors=no \
--run-libc-freeres=no \
-v ./test
結果は以下。
==1424== Memcheck, a memory error detector
==1424== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==1424== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==1424== Command: ./test
==1424==
--1424-- Valgrind options:
--1424-- --tool=memcheck
--1424-- --leak-check=yes
--1424-- --leak-resolution=high
--1424-- --num-callers=40
--1424-- --undef-value-errors=no
--1424-- --run-libc-freeres=no
--1424-- -v
--1424-- Contents of /proc/version:
--1424-- Linux version 4.2.0-1-amd64 (debian-kernel@lists.debian.org) (gcc version 4.9.3 (Debian 4.9.3-5) ) #1 SMP Debian 4.2.6-1 (2015-11-10)
--1424--
--1424-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-rdtscp-sse3-avx
--1424-- Page sizes: currently 4096, max supported 4096
--1424-- Valgrind library directory: /usr/lib/valgrind
--1424-- Reading syms from /home/vagrant/tmp/test
--1424-- Reading syms from /lib/x86_64-linux-gnu/ld-2.19.so
--1424-- Considering /lib/x86_64-linux-gnu/ld-2.19.so ..
--1424-- .. CRC mismatch (computed 809091d5 wanted 33fd79cd)
--1424-- Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.19.so ..
--1424-- .. CRC is valid
--1424-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--1424-- Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--1424-- .. CRC mismatch (computed 2611121c wanted fdf174ed)
--1424-- Considering /usr/lib/debug/usr/lib/valgrind/memcheck-amd64-linux ..
--1424-- .. CRC is valid
--1424-- object doesn't have a dynamic symbol table
--1424-- Scheduler: using generic scheduler lock implementation.
--1424-- Reading suppressions file: /usr/lib/valgrind/default.supp
==1424== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-1424-by-vagrant-on-???
==1424== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-1424-by-vagrant-on-???
==1424== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-1424-by-vagrant-on-???
==1424==
==1424== TO CONTROL THIS PROCESS USING vgdb (which you probably
==1424== don't want to do, unless you know exactly what you're doing,
==1424== or are doing some strange experiment):
==1424== /usr/lib/valgrind/../../bin/vgdb --pid=1424 ...command...
==1424==
==1424== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==1424== /path/to/gdb ./test
==1424== and then give GDB the following command
==1424== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=1424
==1424== --pid is optional if only one valgrind process is running
==1424==
--1424-- REDIR: 0x4017960 (ld-linux-x86-64.so.2:strlen) redirected to 0x3809e1b1 (vgPlain_amd64_linux_REDIR_FOR_strlen)
--1424-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--1424-- Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--1424-- .. CRC mismatch (computed 0900b121 wanted bb491432)
--1424-- Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--1424-- .. CRC is valid
--1424-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--1424-- Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--1424-- .. CRC mismatch (computed d60576bf wanted 177f5f93)
--1424-- Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--1424-- .. CRC is valid
==1424== WARNING: new redirection conflicts with existing -- ignoring it
--1424-- old: 0x04017960 (strlen ) R-> (0000.0) 0x3809e1b1 vgPlain_amd64_linux_REDIR_FOR_strlen
--1424-- new: 0x04017960 (strlen ) R-> (2007.0) 0x04c2c0e0 strlen
--1424-- REDIR: 0x4017710 (ld-linux-x86-64.so.2:index) redirected to 0x4c2bc80 (index)
--1424-- REDIR: 0x4017930 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2d190 (strcmp)
--1424-- REDIR: 0x4018660 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c303b0 (mempcpy)
--1424-- Reading syms from /lib/x86_64-linux-gnu/libpthread-2.19.so
--1424-- Considering /lib/x86_64-linux-gnu/libpthread-2.19.so ..
--1424-- .. CRC mismatch (computed f433f5b8 wanted a1539920)
--1424-- Considering /usr/lib/debug/lib/x86_64-linux-gnu/libpthread-2.19.so ..
--1424-- .. CRC is valid
--1424-- Reading syms from /lib/x86_64-linux-gnu/libc-2.19.so
--1424-- Considering /lib/x86_64-linux-gnu/libc-2.19.so ..
--1424-- .. CRC mismatch (computed f7678cca wanted c4a92976)
--1424-- Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.19.so ..
--1424-- .. CRC is valid
--1424-- REDIR: 0x50d7e20 (libc.so.6:strcasecmp) redirected to 0x4a23730 (_vgnU_ifunc_wrapper)
--1424-- REDIR: 0x50da110 (libc.so.6:strncasecmp) redirected to 0x4a23730 (_vgnU_ifunc_wrapper)
--1424-- REDIR: 0x50d75f0 (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a23730 (_vgnU_ifunc_wrapper)
--1424-- REDIR: 0x50d5970 (libc.so.6:rindex) redirected to 0x4c2b960 (rindex)
--1424-- REDIR: 0x50ce990 (libc.so.6:calloc) redirected to 0x4c2ab60 (calloc)
--1424-- REDIR: 0x50de7b0 (libc.so.6:strchrnul) redirected to 0x4c2fee0 (strchrnul)
--1424-- REDIR: 0x50d77d0 (libc.so.6:__GI_mempcpy) redirected to 0x4c300e0 (__GI_mempcpy)
--1424-- REDIR: 0x50ce020 (libc.so.6:malloc) redirected to 0x4c28be0 (malloc)
--1424-- Reading syms from /lib/x86_64-linux-gnu/libgcc_s.so.1
--1424-- Considering /lib/x86_64-linux-gnu/libgcc_s.so.1 ..
--1424-- .. CRC mismatch (computed de5828bf wanted 0f4d8de1)
--1424-- object doesn't have a symbol table
--1424-- REDIR: 0x50d3c70 (libc.so.6:strlen) redirected to 0x4c2c020 (strlen)
--1424-- REDIR: 0x50ce660 (libc.so.6:free) redirected to 0x4c29e40 (free)
==1424==
==1424== HEAP SUMMARY:
==1424== in use at exit: 1,942 bytes in 6 blocks
==1424== total heap usage: 6 allocs, 0 frees, 1,942 bytes allocated
==1424==
==1424== Searching for pointers to 6 not-freed blocks
==1424== Checked 8,483,328 bytes
==1424==
==1424== 272 bytes in 1 blocks are possibly lost in loss record 4 of 6
==1424== at 0x4C2AC15: calloc (vg_replace_malloc.c:711)
==1424== by 0x4010FE1: allocate_dtv (dl-tls.c:296)
==1424== by 0x40116ED: _dl_allocate_tls (dl-tls.c:460)
==1424== by 0x4E3DC27: allocate_stack (allocatestack.c:589)
==1424== by 0x4E3DC27: pthread_create@@GLIBC_2.2.5 (pthread_create.c:495)
==1424== by 0x400728: main (test.c:16)
==1424==
==1424== LEAK SUMMARY:
==1424== definitely lost: 0 bytes in 0 blocks
==1424== indirectly lost: 0 bytes in 0 blocks
==1424== possibly lost: 272 bytes in 1 blocks
==1424== still reachable: 1,670 bytes in 5 blocks
==1424== suppressed: 0 bytes in 0 blocks
==1424== Reachable blocks (those to which a pointer was found) are not shown.
==1424== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1424==
==1424== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1424== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
この部分が「リークしているかも」と言われている。
これは明らかに pthread_create
した分。
==1424== 272 bytes in 1 blocks are possibly lost in loss record 4 of 6
==1424== at 0x4C2AC15: calloc (vg_replace_malloc.c:711)
==1424== by 0x4010FE1: allocate_dtv (dl-tls.c:296)
==1424== by 0x40116ED: _dl_allocate_tls (dl-tls.c:460)
==1424== by 0x4E3DC27: allocate_stack (allocatestack.c:589)
==1424== by 0x4E3DC27: pthread_create@@GLIBC_2.2.5 (pthread_create.c:495)
==1424== by 0x400728: main (test.c:16)
うーむ・・・。