2015-01-08 15 views
12

私はLearn C The Hard WayからC言語を学んでいます。私はexercise 6です。私はそれを動作させることができますが、valgrindは多くのエラーを再現します。ここで非常に単純なCプログラムのValgrindはエラーを報告します

はファイルex6.cからストリップダウン最小限のプログラムです:Makefile

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    char initial = 'A'; 
    float power = 2.345f; 

    printf("Character is %c.\n", initial); 
    printf("You have %f levels of power.\n", power); 

    return 0; 
} 

コンテンツがちょうどCFLAGS=-Wall -gです。

私は$ make ex6でプログラムをコンパイルします(コンパイラの警告やエラーはありません)。 $ ./ex6を実行すると、期待される出力が得られます。

$ valgrind ./ex6でプログラムを実行すると、解決できないエラーが発生します。完全な出力は次のとおりです。

==69691== Memcheck, a memory error detector 
==69691== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==69691== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info 
==69691== Command: ./ex6 
==69691== 
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option 
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times) 
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times) 
==69691== Conditional jump or move depends on uninitialised value(s) 
==69691== at 0x1003FBC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib) 
==69691== by 0x1001EFBB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001FA005: __vfprintf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x10021F9CE: __v2printf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x100000F1B: main (ex6.c:8) 
==69691== 
Character is A. 
==69691== Invalid read of size 32 
==69691== at 0x1003FBC1D: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib) 
==69691== by 0x1001EFBB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001FA005: __vfprintf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x10021F9CE: __v2printf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib) 
==69691== by 0x100000F31: main (ex6.c:9) 
==69691== Address 0x100809680 is 32 bytes before a block of size 32 in arena "client" 
==69691== 
You have 2.345000 levels of power. 
==69691== 
==69691== HEAP SUMMARY: 
==69691==  in use at exit: 39,365 bytes in 429 blocks 
==69691== total heap usage: 510 allocs, 81 frees, 45,509 bytes allocated 
==69691== 
==69691== LEAK SUMMARY: 
==69691== definitely lost: 16 bytes in 1 blocks 
==69691== indirectly lost: 0 bytes in 0 blocks 
==69691==  possibly lost: 13,090 bytes in 117 blocks 
==69691== still reachable: 26,259 bytes in 311 blocks 
==69691==   suppressed: 0 bytes in 0 blocks 
==69691== Rerun with --leak-check=full to see details of leaked memory 
==69691== 
==69691== For counts of detected and suppressed errors, rerun with: -v 
==69691== Use --track-origins=yes to see where uninitialised values come from 
==69691== ERROR SUMMARY: 5 errors from 2 contexts (suppressed: 0 from 0) 

私はOS Xのyosemiteです。 Valgrindはbrew経由でインストールされ、このコマンドは$ brew install valgrind --HEADです。

だから、誰でも問題が何であるか知っていますか? valgrindエラーを修正するにはどうすればよいですか?

+0

外部ライブラリにリンクしていますか? –

+2

私のLinuxでは、この例ではエラーは報告されません。関連リンクのサイドバーには、[抑制ファイルの使用を提案するもの](http://stackoverflow.com/questions/5226691/valgrind-mac-os-mem-leak?rq=1)があります。 –

+0

@IngoLeonhardt: 'float'型の可変引数は' double'に昇格されるので、問題ではありません。 (正確なプロトタイプは ''に含まれていました。) –

答えて

12

Valgrindを使用して実行しているプログラムが質問に投稿したプログラムと正確に同じであれば、明らかにメモリリークはありません。実際には、自分でmalloc/freeを使用することさえありません!

これは、Valgrindがwhat happened to myself some time agoに似たOS X(唯一の!)で検出する擬似エラー/偽陽性のようです。

他のオペレーティングシステムにアクセスしている場合(例: Linuxマシンでは、そのシステム上でValgrindを使用してプログラムを分析しようとします。

EDIT:私は今のマックへのアクセスを持っていないので、私自身は、これを試していないが、しかし、あなたは M Oehmが提案するもの試してみてください:try to use a supressions file as mentioned in this other SO questionを。

+0

OS X Yosemiteの抑制ファイルが見つかりませんでした。そのSA答えからのものは、Valgrindの出力に何の影響も与えなかった。一方、laginuxで同じ手順を実行することで、Valgrindの出力がきれいになりました。 –

+0

自分のマシンでこれを確認しました。私はこの単純なプログラムをMac OS Xで複製し、Valgrindと一緒に走り、条件付きジャンプをしました。 – brandaemon

1

thisから判断すると、valgrindはプラットフォーム上で正しい結果が得られるとは限りません。可能であれば、別のプラットフォームでこのコードを試してみてください。

原因は、valgrid自体またはシステム実装printfであり、両方とも修正することは実際的ではありません。

Rerun with --leak-check=full to see details of leaked memory.これは、発生しているリークに関するさらに詳しい情報を提供します。何も役立たない場合は、suppression fileを作成して、エラーの表示を停止することができます。

+0

残念ながら、現在「無効なサイズ32の読み取り」の抑制ファイルを作成することはできません。 Darwinポートにはこの新しいエラーがありますが、16より大きいサイズのエラーを抑止する機能はサポートされていません。これを実現するには時間がかかるでしょう(些細な修正と思われます)。 – antirez

10

この問題は、Xcode6.2ではValgrind r14960 with VEX r3124、Xcode 6.3ではValgrind r15088を使用するDarwin 14.3.0(Mac OS X 10.10.2)では修正されています。

Macportsを使用している場合(この執筆時点で)、sudo port install valgrind-develValgrind r14960 with VEX r3093を提供します。

ここに私のビルドスクリプトはValgrind r14960 with VEX r3124をインストールすることです:

#! /usr/bin/env bash 

mkdir -p buildvalgrind 
cd buildvalgrind 
svn co svn://svn.valgrind.org/valgrind/trunk/@14960 valgrind 
cd valgrind 
./autogen.sh 
./configure --prefix=/usr/local 
make && sudo make install 

# check that we have our valgrind installed 
/usr/local/bin/valgrind --version 

(参照:http://calvinx.com/2015/04/10/valgrind-on-mac-os-x-10-10-yosemite/

マイMacPortsのインストールされたvalgrindのは/opt/local/bin/valgrindに位置しています。

私は今

/opt/local/bin/valgrind --leak-check=yes --suppressions=`pwd`/objc.supp ./ex6

を実行する場合、私はあなたが上記と全く同じエラーが発生します。

を(ここではhttps://gist.github.com/calvinchengx/0b1d45f67be9fdca205bobjc.suppファイルを使用して)しかし、私は予想通り

/usr/local/bin/valgrind --leak-check=yes --suppressions=`pwd`/objc.supp ./ex6

すべての作品実行する場合、私は、システム・レベルのメモリーリークエラーが現れて得ることはありません。

関連する問題