2010-11-18 30 views
0

これは私の以前のValgrindの質問よりも重視されています。私は書き込みを絞り込むと、コマンドラインオプションの解析時に読み取りエラーをしようとしています:無効な書き込みエラーを報告するValgrind

#include <stdio.h>                                                      
#include <stdlib.h>                                                     
#include <unistd.h>                                                     
#include <sys/utsname.h>                                                    
#include <sys/stat.h>                                                     
#include <string.h>                                                     
#include <locale.h>                                                     
#include <bzlib.h>                                                      
#include <zlib.h>                                                      
#include "starch.h" 

#define BUFMAXLEN 1024 

int main(int argc, char **argv) { 
    if (parseCommandLineInputs(&argc, &argv) != 0) 
     exit(EXIT_FAILURE); 

    return 0; 
} 

int parseCommandLineInputs(int *argc, char ***argv) { 

    pid_t pid;                                                       
    struct utsname uts; 
    char uniqTag[BUFMAXLEN]; 

    if ((*argc == 1) || (*argc > 4)) {                                                 
     printUsage(); 
     return -1;                                                   
    }                                                         

    if ((pid = getpid()) < 0) {                                                  
     fprintf(stderr, "\n\t[starch] - Error: Could not obtain process ID\n\n");                                      
     return -1;                                                   
    }                                                         
    uname(&uts);                                                      
    sprintf(uniqTag, "pid%d.%s", pid, uts.nodename);                                             

    switch (*argc) {                                                     
     case 2: {                                                      
      if (strcmp(*argv[1], "-") != 0) {                                               
       if (fileExists(*argv[1]) != 0) { /* standard input */                                        
        ... 
    } 

    return 0; 
} 


int fileExists(char *fn) { 
    struct stat buf; 
    int i = stat (fn, &buf); 
    if (i == 0) 
     return 0; 
    return -1; 
} 

void printUsage() { 
    fprintf(stderr, "my usage statement\n\n"); 
} 

次のように私のメイクファイルは次のとおりです。

CC  = gcc                                                       
CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -DUSE_ZLIB -O3 -Wformat -Wall -pedantic -std=gnu99 -g                               
BIN  = ../bin                                                      

all: starch                                                       
    rm -rf *~                                                       

starch: starch.o                                                      
    mkdir -p $(BIN) && $(CC) ${CFLAGS} starch.o -lbz2 -lz -o ${BIN}/starch                                        
    rm -rf *~                                                       

clean: 
    rm -rf *.o *~ ${BIN}/starch 

私はvalgrindで実行したとき、私は次のエラーを取得:

$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes -v ../bin/starch 

... 

==2675== 1 errors in context 1 of 2:                                                 
==2675== Invalid read of size 8                                                  
==2675== at 0x3AB4262243: fwrite (in /lib64/libc-2.5.so)                                           
==2675== Address 0x7fedffd68 is on thread 1's stack                                             
==2675==                                                        
==2675==                                                        
==2675== 1 errors in context 2 of 2:                                                 
==2675== Invalid write of size 8                                                  
==2675== at 0x401AA6: parseCommandLineInputs (starch.c:217)                                           
==2675== by 0x7FF0000AF: ???                                                  
==2675== by 0x401DFA: main (starch.c:46)                                               
==2675== Address 0x7fedffd68 is on thread 1's stack 

fwrite()をどこにも使用していないため、最初にエラーが表示されません。

fprintfステートメントの2番目のエラーがprintUsage()にトリックアップされています。

fprintf(stderr, "my usage statement\n\n"); 

これらのエラーが表示される理由を説明し、私のアプリケーションの何が問題になっている:

if (parseCommandLineInputs(&argc, &argv) != 0) 

ライン217は、次の行がある:

ライン46は、次の行ですか?

+1

これは完全なプログラムではありません( '#include '、' uts'、 'uniqTag'、または' pid'の定義はありません)。 'parseCommandLineInputs'の行が末尾のスペースでいっぱいになるのはなぜですか? – pmg

+0

情報の半分だけでプログラムをデバッグする方法はありますか? uts、uniqTagはどこですか? starch.cの46行目と217行目は何ですか? --db-attach = yesを使って試してみましたか? – BatchyX

答えて

4

2つのこと:

  • * ARGV [1](* ARGV)と同じではない[1]あなたはおそらく何を意味するかです。配列の添字は、ポインタ逆参照よりも優先されます。この結果、無効なポインターになります。多くの経験豊富なプログラマーが次のように述べています。「演算子の優先順位を覚えようとしないでください。疑問がある場合はかっこを使ってください。

  • コンパイラフラグの-O3は、デバッグ時に大きな負担となります。コンパイラはあなたの人生を不可能にするほど多くのコードを絡ませるでしょう。変数は完全に消える可能性があり、インライン化すると関数は不思議に遠ざかります。コードがコンパイルされている場合、-O0(IIRCのインラインアセンブリを含むコードには-O1とGCCバージョンの両方が含まれています)をリンクして実行してください。そうでない場合は-O1を使用してください。

+0

ご協力いただきありがとうございます。私は 'malloc/sprintf'文を' strdup'文で置き換えました。何らかの理由で、これはvalgrindエラーメッセージを修正しました。 –

0

紛失が多すぎるため、何が起こっているのかを簡単に伝えることができません。 pidpid_tだと思いますか?私はその後、参照 唯一のものは、このいずれかになります。

sprintf(uniqTag, "pid%d.%s", pid, uts.nodename); 

pid_tは必ずしもintがそうsprintfは、その引数を解析する際に間違ったトラックにあることや、あなたのスタックをmessupかもしれないです。しかし、gccは、あなたが-Wallとコンパイルするとあなたに語ったはずです。

別のコンパイラでコンパイルしてみてください。すぐに私にポップアップ表示

関連する問題