2011-12-24 3 views
2

valgrindの範囲内で、Cのバイナリのデバッグバージョンを実行しています。これは、多くの種類のエラーであるConditional jump or move depends on uninitialised value(s)を返します。シンボルテーブルを使用してこの関数の初期化されていない値はどこですか?

valgrindは、この問題のために私のプログラムに見えるように私に告げる:

==23899== 11 errors in context 72 of 72:                                                  
==23899== Conditional jump or move depends on uninitialised value(s)                                           
==23899== at 0x438BB0: _int_free (in /foo/bar/baz)                               
==23899== by 0x43CF75: free (in /foo/bar/baz)                                
==23899== by 0x4179E1: json_tokener_parse_ex (json_tokener.c:593)                                           
==23899== by 0x418DC8: json_tokener_parse (json_tokener.c:108)                                            
==23899== by 0x40122D: readJSONMetadataHeader (metadataHelpers.h:345)                                        
==23899== by 0x4019CB: main (baz.c:90) 

私はjson_tokener_parse()を呼び出して、次の機能readJSONMetadataHeader(...)あります

int readJSONMetadataHeader(...) {                                                                                         
    char buffer[METADATA_MAX_SIZE]; 
    json_object *metadataJSON; 
    int charCnt = 0; 
    ... 
    /* fill up the `buffer` variable here; basically a */ 
    /* stream of characters representing JSON data... */ 
    ... 
    /* terminate `buffer` */ 
    buffer[charCnt - 1] = '\0'; 
    ... 
    metadataJSON = json_tokener_parse(buffer); 
    ... 
} 

の機能json_tokener_parse()で次のようになります。

struct json_object* json_tokener_parse(const char *str)                                              
{                                                            
    struct json_tokener* tok;                                                     
    struct json_object* obj;                                                     

    tok = json_tokener_new();                                                     
    obj = json_tokener_parse_ex(tok, str, -1);                                                 
    if(tok->err != json_tokener_success)                                                  
     obj = (struct json_object*)error_ptr(-tok->err);                                               
    json_tokener_free(tok);                                                      
    return obj;                                                         
} 

へのトレースに続いて、json_tokener_parse()に供給されたchar [](またはconst char *)変数bufferが初期化されていない値のように見え、json_tokener_parse_ex()に供給されます。

しかし、変数がデータで満たされてから、json_tokener_parse()関数が呼び出される前に終了します。

なぜ、valgrindはこの値が初期化されていないと言っていますか?私は何が欠けていますか?

+0

あなたのコードとコメントが何かであれば、 'charCnt'は使用時に初期化されません。 – GManNickG

+0

あるいは 'buffer'はユニット化されています。ちょうどNULで終了します。 – cnicutar

+0

明快さに欠けて申し訳ありません。 'buffer'が' char'値で設定されると、 'charCnt'値がインクリメントされます。また、関連する変数のみをコピーして貼り付けています。私はそれが '0'に初期化されていることを書き留めることを忘れていますが、これは現在修正されています。ありがとう! –

答えて

2

charCntが初期化されていません。

bufferから来ているかどうかを確認するには、単純に= {0}で初期化します。これにより、バッファのヌル終了が廃止されます。

+0

'{0}'を 'buffer'に追加しようとしましたが、私は同じエラーと同じ関数と同じ行を続けます。 –

1

あなたが表示されないjson_tokener_parse_ex()をご覧ください。初期化されていないものを解放しようとしている可能性があります。

1
buffer[charCnt - 1] = '\0'; 

charCntがゼロであることを起こる場合、これは少なくともは失敗します。

+0

ありがとうございます。空の 'buffer'がメタデータを持たないため、アプリケーションはエラー状態(コードはわかりやすくするために図示していません)で早期に終了するので、これを潜在的な原因として削除しました。 –

2

アプリケーションが静的にリンクされているように(特にfreeがメインの実行可能ファイルに含まれ、libc.so.6ではなく)表示されているように、valgrindエラーレポートが表示されます。

Valgrindは、静的にリンクされたアプリケーションの偽のエラーを報告します。

もっと正確に言えば、libcには意図的な「ドントケア」エラーがあります。アプリケーションを動的にリンクすると、そのようなエラーはデフォルトで抑制されます(Valgrindに付属する抑制ファイルを介して)。

しかし、アプリケーションを静的にリンクすると、Valgrindは障害のあるコードがlibc.aに由来することを知らないので、それらを報告します。

一般的にLinux上でアプリケーションを静的にリンクすることは悪い考えです(TM)。

Valgrindの下で、このようなアプリケーションを実行している:それはValgrindのはmalloc/free呼び出しをインターセプトすることができなくなり、かつ効果的にのみ初期化されていないメモリの読み取りをキャッチし、ないヒープバッファオーバーフロー(または他のヒープ破損のバグ)になること:二重そう通常は良いです。

関連する問題