4

ここに私のコードのスニペットを投稿します。私はデバッグに足を踏み入れようとしています。

struct dirent *s_dirent;
char path[300];
....
bzero(path,300);
...
fd_dir = opendir(path);
while((s_dirent = readdir(fd_dir))!=NULL)
{
     if(s_dirent->d_name[0] == '.')
          continue;
     else
          break;
 }
if(s_dirent == NULL)
{
   if(closedir(fd_dir)!=0)
       perror("Error on closedir");
 }
else
{

  if(closedir(fd_dir)!=0)/*Line number 249*/
      perror("Error on closedir");

  /*some comments*/
  strcat(path,"/");
  strcat(path,s_dirent->d_name);/*Line number 254*/
 }

Valgrindの出力:

==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)
==3287==    by 0x804D6B4: online_bck (backup_manager.c:254)
==3287==    by 0x8049F96: on_bck_beg (TxFS_manager.c:181)
==3287==    by 0x8049818: handler (Reader.c:236)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)
==3287==  Address 0x402a39b is 35 bytes inside a block of size 32,792 free'd
==3287==    at 0x40057F6: free (vg_replace_malloc.c:325)
==3287==    by 0xAF6C67: closedir (in /lib/libc-2.12.90.so)
==3287==    by 0x804D65A: online_bck (backup_manager.c:249)
==3287==    by 0x8049F96: on_bck_beg (TxFS_manager.c:181)
==3287==    by 0x8049818: handler (Reader.c:236)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)

どんな助けでも大歓迎です。ありがとう

4

3 に答える 3

5

readdir()を呼び出した後に返されるデータにはアクセスしないでくださいclosedir()。これはclosedir()、opendir / readdirに割り当てられているリソース(メモリなど)を解放する可能性があるためです。

dirent *構造体を保存したい場合はreaddir_r、readdirのバリアントに切り替えることができます(パラメーターのセットが異なります)。

更新:Valgrind出力のデコード:

        V - note single space here; it is beginning of error message. 
==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)

 backtrace skipped

Valgrindによると、エラーはReading of invalid data, sized 1 byteであり、これはメモリリークではありません。不正なメモリアクセスです。そして、この読み取りのアクターはstrcat()(スキップされたバックトレースによって呼び出されます)です。なぜデータが無効なのですか?サブメッセージがあります

        VV - note two spaces here, it is continuation of error message
==3287==  Address 0x402a39b is 35 bytes inside a block of size 32,792 free'd
==3287==    at 0x40057F6: free (vg_replace_malloc.c:325)
==3287==    by 0xAF6C67: closedir (in /lib/libc-2.12.90.so)

バイトはfree-dされたメモリセグメントの一部であるため無効です(読み取りは許可されていません)(free-dしたばかりのメモリから読み取ることはできません)。誰がこれをしましたか?バックトレースを見てください:closedir無料の発信者でした。

于 2011-08-06T02:28:43.793 に答える
0

s_dirent == NULLwhileループ終了条件を確認してください。

于 2011-08-06T02:13:34.790 に答える
0

に到達するまでにstrcat()、whileループはすでに終了しています。whileループが1回終了するs_direntとNULLになります。

ただし、s_directNULLになるとすぐに、次のように実行します。

strcat(path,"/");
strcat(path,s_dirent->d_name);/*Line number 254*/

...これはs_direntを逆参照しようとします。したがって、valgrindは、backup_manager.c:254から呼び出されているstrcat()の呼び出しを確認するように指示します。

==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)
==3287==    by 0x804D6B4: online_bck (backup_manager.c:254)

これは、「。」、「..」のエントリを含む空のディレクトリ、または「。」で始まる隠しファイルのみを含むディレクトリを処理している場合にのみ発生すると思いますか?

于 2011-08-06T02:20:51.290 に答える