2011-10-19 11 views
3

GDBとValgrindを使用しようとしましたが、問題を特定できないようです。 興味深いことに、通常の実行とGDBではプログラムがクラッシュしますが、Valgridではクラッシュしません。 ソケットとUDPを介してサーバーと通信してファイルを転送し、基本的なパケット損失を処理します。コードは次のようになります。 malloc memory corruption、fopen

サーバーのコードは共有されません。なぜなら、問題は存在しないことがわかっているからです。 いくつかを混乱させるかもしれない点は、私は数字ジェネレータを使って自分自身でパケット損失を実装していることです。現在、プログラムで別のrecvfromを使用するだけでなく、実際には何もしません。

クライアントはプログラムの出力を案内するために、クライアントはサーバーにどのファイルが必要かを伝えます。サーバーはクライアントにファイルの送信量を通知し、 )。

出力には、送信されたチャンク、受信された文字の数、および連結された文字列が表示されます。

ファイル転送は、私が問題を引き起こしている受信ファイルを書き込むために使用しているfopen呼び出しだけで成功します。それが私のmallocコールと関係があるかどうかわからない。ここで

は、ソースコードである:ここで

pastebin.com/Z79hvw6L

は、CLIの実行、およびValgrindの出力は(GDBは、任意のより多くの情報を与えていないようです)、次のとおりです。

CLIがmallocメモリ破損エラーを表示し、Valgrindがエラーを返すことに注意してください。

CLI:http://pastebin.com/qdTKMCD2

Valgrindは:任意の助けhttp://pastebin.com/8inRygnU

ありがとう!

は、GDBバックトレースは、エラーがプログラムのどの部分であるために、これは誰かに洞察力を与えることができるかもしれない

======= Backtrace: ========= 
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x19a961] 
/lib/i386-linux-gnu/libc.so.6(+0x6e15d)[0x19d15d] 
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x19ef53] 
/lib/i386-linux-gnu/libc.so.6(+0x5c2b8)[0x18b2b8] 
/lib/i386-linux-gnu/libc.so.6(fopen+0x2c)[0x18b38c] 
/home/---/client[0x8048dc2] 
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x145e37] 
/home/---/client[0x8048871] 

を結果を追加しましたか?

+3

一般的に、投稿の文脈内で関連するソースサブセットを投稿できない場合、多くの回答は得られません。 – Joe

+0

valgrindでクラッシュした場所のバックトレースを投稿してみませんか?私はあなたがそのバックトレースを取得した場合、壊れたメモリ(クラッシュのポイント)にメモリウォッチポイントを設定すると、問題につながると思います。 – dbeer

+0

ジョーってどういう意味ですか?問題はどこにあるのだろうか? – user974703

答えて

3
char chunk[10]; 
chunk[10] = '\0'; 

が間違っている場合、チャンク[10]は1つ前の配列です。

そして一般的には、あなたが長いファイル名を入力した場合、あなたはメモリをゴミ箱ます。この

char filename[25]; 
scanf("%s",filename); 

を行うには注意してください。 fgets()を使う方が良いでしょう。また、少なくともscanfが成功するかどうかをチェックしたい場合は、filenameの次のstrlen()が有効でないことを確認してください。

行93、buf[strlen(buf)-1]='\0';は危険です。バッファがまだヌル終了していない場合はstrlenを使用できません。buf [-1]のインデックスを作成すると、bufが空の文字列の場合はメモリをゴミ箱に入れます。

編集。 あなたの他の問題はstrcat(fullstring,chunk);です。あなたが保持できるより多くのデータを受け取った場合、この文字列への追加を停止するループのコントロールはありません。最後のヌルターミネーターのためのスペースが必要なので、サイズは1つ外れる可能性もあります。それを少なくともchar * fullstring = malloc(sizeof(char)*filesize + 1);にしてください。しかし、あなたのループは、それがそのバッファの終わりを過ぎて書き込まれていないことを確認する必要があります。

ヌルターミネータをbufに追加すると、recv呼び出しによって読み取られたバイト数が返されるため、recvでエラーをチェックした場合はbuf[numbytes] = 0となりますが、 bufのために10バイトを割り当てて、それに10バイトも読み込もうとしますが、Cでは、文字列にもヌルターミネータのためのスペースが必要です。 bufを11バイト大きくする。またはrecv()は9バイトのみです。

実際には、1つの場所が多いので、必要なバイト数を数え始めて、それらに何かを入れています。この(ライン99100

buf[strlen(buf)-1]='\0'; 

UPDATE:Cにおいて、アレイは、インデックスゼロで始まり、そして10のアレイのみ

+0

はチャンク[10]ビットを変更しましたが、結果はありません。私はファイル名をそのまま残しています。いったん動作したら、エラーチェックをします。 bufがnullで終了しないことが分かっている場合、strlenなしでヌルターミネータを追加するにはどうすればよいですか? – user974703

+0

お返事ありがとうございました。回答は、私は完全な文字列とチャンクの境界から脱出していたということでした。私はあなたの提案のようにフルストリングを増やさなければならず、ヌルは各チャンクを適切に終了させます。 その他の問題を修正します。 – user974703

1

最近のOSでは問題はありませんが、malloc()から返された値をNULLとしてチェックしません。どのラインでクラッシュするのですか?

+0

fopenでクラッシュすると、どのようなシグナルがクラッシュするのかをどのように知ることができますか?もしそれがあなたが意味することであれば、それはMallocの記憶腐敗だと言います。 – user974703

2

9にインデックス0によってインデックス付けすることができる。この(ライン93)が疑わしいことを思い出してください)も間違っている:

char chunk[10]; 
chunk[10] = '\0'; 

アップデート2:バッファが

char * fullstring = malloc(sizeof(char)*filesize); // line 103 
... 
strcat(fullstring,chunk); // line 124 

Update3と小さすぎる: UDPは信頼できません。パケットの送信に失敗する可能性があり(送信者と受信者の間のどこにでもパケットがドロップされる可能性があります)、送信した順序とは異なる順序でパケットが受信される可能性があります。

+0

誰か(nos)が既にそれを見ました。 – wildplasser