Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Readdir/closedir-Valgrind显示;无效的read";_C_Linux_Valgrind_Readdir - Fatal编程技术网

Readdir/closedir-Valgrind显示;无效的read";

Readdir/closedir-Valgrind显示;无效的read";,c,linux,valgrind,readdir,C,Linux,Valgrind,Readdir,在这里发布我的代码片段。我正试图在调试方面站稳脚跟 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; }

在这里发布我的代码片段。我正试图在调试方面站稳脚跟

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)
        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
我们将非常感谢您的帮助。
感谢
s\u dirent==NULL
,检查
while
循环退出条件。

当您到达
strcat()
时,您已经退出while循环。当
s\u dirent
为空时,while循环退出一次

但只要
s_direct
为空,您就可以运行以下命令:

strcat(path,"/");
strcat(path,s_dirent->d_name);/*Line number 254*/
…试图取消对s_dirent的引用。因此,valgrind然后告诉您检查从backup_manager调用strcat()的调用。c:254:

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

我猜只有在处理包含“.”“…”项的空目录或仅包含以“.”开头的隐藏文件的目录时,您才会遇到此问题。

您不应该访问调用
closedir()
后由
readdir()
返回的数据。这是因为
closedir()

如果要保存dirent*struct,可以切换到readdir的变体(使用不同的参数集)

更新: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)
        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说错误是读取无效数据,大小为1字节,这不是内存泄漏。这是不正确的内存访问。这次读取的参与者是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)

该字节无效(不允许从中读取),因为它是空闲-d内存段的一部分(不能从刚空闲-d的内存中读取)。这是谁干的?查看backtrace:
closedir
是免费的调用者。

我很抱歉没有发布大部分代码。我做到了now@Steave-o很抱歉,我没有像以前那样邮寄空支票。但我已经检查过这种情况。谢谢你的关注,很抱歉没有像我以前那样把空支票寄出去。但我已经检查过这种情况,这并不是导致错误的原因。感谢您的关注者,在调用closedir()Yes之前,可以将其复制到其他地方,但是readdir\r将直接将dirent放置到用户提供的缓冲区中,而不复制。我应该说,我的答案纯粹是猜测,readdir/closedir的Linux、SUS和Solaris手册页都没有描述您的情况。但是Valgrind output说,strcmp试图访问free-d数据,而closedir是唯一可以释放它的人。虽然您的说法听起来似乎有道理,但readdir()或closedir()手册页都没有提到由readdir()返回的静态缓冲区指针是由closedir()释放的。查看被释放的调用堆栈,看起来确实是这样的:
在0x40057F6:free(vg_replace_malloc.c:325)
由0xAF6C67:closedir(in/lib/libc-2.12.90.so)调用,或者将closedir移动到strcat()之后?@Stéphane:我找不到任何POSIX文档可以释放由
readdir
返回的缓冲区,但这似乎是POSIX中的一个缺陷。显然,他们的意图是将缓冲区置于
DIR
结构中,因为对于一个打开的
DIR
调用
readdir
不允许对另一个
DIR
调用
readdir
返回的
dirent
。除非
closedir
释放缓冲区,否则无法在不泄漏内存的情况下满足这些要求。