fork () вызывает утечку памяти - PullRequest
0 голосов
/ 22 марта 2019

Когда я пытаюсь рекурсивно перемещаться по каталогам в fork.Fork вызывает утечку памяти. Если я просто выполняю fork, все окей, но когда я вызываю функцию в дочернем процессе, я вижу утечку памяти в valgrind. Думаю, я закрываю каждый каталог. Но valgrind говоритopendir_tail.I попытался написать clodir в родительском, но затем я беру 1 выделенную, но 2 свободных ошибки. В чем проблема?

Здесь мой код.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <ctype.h>

int dfsdirectory (char *path){
DIR* dir;   
struct dirent *dirEntry;  
struct stat fileStat;     
char _PathN[1000];       

int totalSize=0;
  if (!(dir = opendir(path))){
    closedir(dir);
    return -1;
  }
  while ( ((dirEntry=readdir(dir)) != 0)  ) {
    int dirSize=0;

    if (strcmp(dirEntry->d_name, ".") == 0 
     || strcmp(dirEntry->d_name, "..") == 0)  
        continue;

    snprintf(_PathN, sizeof(_PathN), "%s/%s", path, dirEntry->d_name);
    lstat (_PathN, &fileStat);

    if (S_ISDIR(fileStat.st_mode)){
        int PID = fork();

        if(PID<0){
            closedir(dir);
            return -1;
        }

        if(PID == 0){
          dfsdirectory(_PathN);
            while ((closedir(dir) == -1) && (errno == EINTR));      
            exit(0);
        } 
        else{                
            wait(NULL);   
        }
    }
}
      closedir(dir);
      return totalSize; 
}

int main() {    
   dfsdirectory("A");   
}

И вывод valgrind

==4070== Memcheck, a memory error detector
==4070== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4070== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright 
info
==4070== Command: ./main
==4070== Parent PID: 953
==4070== 
==4072== 
==4072== HEAP SUMMARY:
==4072==     in use at exit: 32,816 bytes in 1 blocks
==4072==   total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4072== 
==4072== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4072==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4072==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4072==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4072==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4072==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4072== 
==4072== LEAK SUMMARY:
==4072==    definitely lost: 0 bytes in 0 blocks
==4072==    indirectly lost: 0 bytes in 0 blocks
==4072==      possibly lost: 0 bytes in 0 blocks
==4072==    still reachable: 32,816 bytes in 1 blocks
==4072==         suppressed: 0 bytes in 0 blocks
==4072== 
==4072== For counts of detected and suppressed errors, rerun with: -v
==4072== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4071== 
==4071== HEAP SUMMARY:
==4071==     in use at exit: 0 bytes in 0 blocks
==4071==   total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4071== 
==4071== All heap blocks were freed -- no leaks are possible
==4071== 
==4071== For counts of detected and suppressed errors, rerun with: -v
==4071== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4075== 
==4075== HEAP SUMMARY:
==4075==     in use at exit: 65,632 bytes in 2 blocks
==4075==   total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4075== 
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4075==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4075==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4075== 
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4075==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4075==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4075== 
==4075== LEAK SUMMARY:
==4075==    definitely lost: 0 bytes in 0 blocks
==4075==    indirectly lost: 0 bytes in 0 blocks
==4075==      possibly lost: 0 bytes in 0 blocks
==4075==    still reachable: 65,632 bytes in 2 blocks
==4075==         suppressed: 0 bytes in 0 blocks
==4075== 
==4075== For counts of detected and suppressed errors, rerun with: -v
==4075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4076== 
==4076== HEAP SUMMARY:
==4076==     in use at exit: 65,632 bytes in 2 blocks
==4076==   total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4076== 
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4076==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4076==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4076== 
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4076==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4076==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076==    by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4076==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4076== 
==4076== LEAK SUMMARY:
==4076==    definitely lost: 0 bytes in 0 blocks
==4076==    indirectly lost: 0 bytes in 0 blocks
==4076==      possibly lost: 0 bytes in 0 blocks
==4076==    still reachable: 65,632 bytes in 2 blocks
==4076==         suppressed: 0 bytes in 0 blocks
==4076== 
==4076== For counts of detected and suppressed errors, rerun with: -v
==4076== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4074== 
==4074== HEAP SUMMARY:
==4074==     in use at exit: 32,816 bytes in 1 blocks
==4074==   total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4074== 
==4074== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4074==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4074==    by 0x4EEB813: __alloc_dir (opendir.c:247)
==4074==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4074==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4074==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4074== 
==4074== LEAK SUMMARY:
==4074==    definitely lost: 0 bytes in 0 blocks
==4074==    indirectly lost: 0 bytes in 0 blocks
==4074==      possibly lost: 0 bytes in 0 blocks
==4074==    still reachable: 32,816 bytes in 1 blocks
==4074==         suppressed: 0 bytes in 0 blocks
==4074== 
==4074== For counts of detected and suppressed errors, rerun with: -v
==4074== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4073== 
==4073== HEAP SUMMARY:
==4073==     in use at exit: 0 bytes in 0 blocks
==4073==   total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4073== 
==4073== All heap blocks were freed -- no leaks are possible
==4073== 
==4073== For counts of detected and suppressed errors, rerun with: -v
==4073== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4070== 
==4070== HEAP SUMMARY:
==4070==     in use at exit: 0 bytes in 0 blocks
==4070==   total heap usage: 1 allocs, 1 frees, 32,816 bytes allocated
==4070== 
==4070== All heap blocks were freed -- no leaks are possible
==4070== 
==4070== For counts of detected and suppressed errors, rerun with: -v
==4070== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Ответы [ 2 ]

3 голосов
/ 22 марта 2019

Эта утечка памяти связана с рекурсией.Вы не закрываете дескрипторы каталога дальше вверх по стеку:

==4075==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4075==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108AE6: main (in /home/alex/Desktop/main)
==4075==    by 0x4EEB902: opendir_tail (opendir.c:145)
==4075==    by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075==    by 0x108AE6: main (in /home/alex/Desktop/main)

Это утечка типа , все еще достижимая , и она может быть безвредной, потому что вы вызываетеexit рано (что применимо здесь), или потому что они ссылаются на структуры данных, которые имеют корни в глобальных переменных.Разработчики на C сильно расходятся во мнениях относительно того, нужно ли устранять эти утечки или допустимо ли оставлять их в программе.

Обратите также внимание, что проверка EINTR для closedir неверна с glibc,Он вводит уязвимость двойного освобождения в случае сбоя EINTR.

0 голосов
/ 24 марта 2019

Я нашел решение. Перед рекурсивным вызовом закройте каталог, и утечки памяти не будет

...