Readdir/closedir - Valgrind shows "invalid read"
Posting snippets of my code here. I am trying to get a footing around debugging.
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_d开发者_运维问答ir)!=0)/*Line number 249*/
perror("Error on closedir");
/*some comments*/
strcat(path,"/");
strcat(path,s_dirent->d_name);/*Line number 254*/
}
Valgrind output:
==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)
Any help will be highly appreciated. Thanks
You should not access data, returned by readdir()
after calling a closedir()
. This is because closedir()
may free any resources (e.g. memory), allocated in opendir/readdir.
If you want to save dirent* struct, you can switch to readdir_r
variant of readdir (with different set of parameters).
UPDATE: Decoding of Valgrind output:
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 says that error is Reading of invalid data, sized 1 byte
, which is not a Memory Leak. It is incorrect memory access. And the actor of this read is the strcat()
(called by skipped backtrace). Why the data is invalid? There is submessage
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)
The byte is invalid (not allowed to be read from) because it is part of memory segment which was free-d (you can't read from the memory you just free-d). Whom did this? Look at backtrace: closedir
was the caller of free.
s_dirent == NULL
, check the while
loop exit condition.
By the time you get to the strcat()
, you've already exited the while loop. The while loop exits once s_dirent
is NULL.
But as soon as s_direct
is NULL, you run this:
strcat(path,"/");
strcat(path,s_dirent->d_name);/*Line number 254*/
...which attempts to dereference s_dirent. Thus, valgrind then tells you to check the call to strcat() being called from backup_manager.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)
I'm guessing you're hitting this only when you're processing an empty directory which contains entries for ".", "..", or directories that only contain hidden files which start with "."?
精彩评论