Rik Van de Velde
Rik Van de Velde

Reputation: 21

Valgrind, Open file descriptors at exit

I'm coding a program in which a parent is executing function and needs to write the results of these function to a pipe. The child has to read the pipe and put everything in a logging file. I forked the parent (which uses the function fifomanager_write(), see below) and the child uses the function fifomanager_write() (see below). I opened a fifo using mkfifo (using FIFO_NAME). I close the fifo file everytime I exit the function but valgrind still mentiones that there are file desriptors open after exiting the programme (see below). Can somebody explain based on my code if I'm missing something?

void fifomanager_read()
{
  int sequencenumber = 1;
  char recv_buf[MAX];
  FILE*fp;
  fp = fopen(FIFO_NAME, "r"); 
  CHECK_FIFOOPEN(fp);
  
  FILE*logfile;
  logfile = fopen(FIFO_LOG, "a"); 
  CHECK_FIFOOPEN(logfile);
  fprintf(logfile, "start of new log\n");
  do  
  {
    fp = fopen(FIFO_NAME, "r");
    CHECK_FIFOOPEN(fp);
    if ( fgets(recv_buf, MAX, fp) != NULL )
    { 
      #ifdef DEBUG
      printf("Message received: %s", recv_buf);
      #endif
      //print to log file
      fprintf(logfile,"%d %ld %s",sequencenumber, time(NULL), recv_buf);
      sequencenumber++; 
    }
  } while(strcmp(recv_buf, "End of logging process\n")!=0); 
  int result = fclose( logfile );
  CHECK_FIFOCLOSED(result);

  result = fclose( fp );
  CHECK_FIFOCLOSED(result);
  #ifdef DEBUG
  printf("both files closed \n");
  #endif
}

void fifomanager_write(char*recv_buf)
{
  FILE*fp;
  fp = fopen(FIFO_NAME, "w");
  CHECK_FIFOOPEN(fp);
  //put a lock as you are putting values in the fifo
  pthread_mutex_lock(&fifolock);
  if ( fputs( recv_buf, fp ) == EOF ) 
  {
    fprintf( stderr, "Error writing data to fifo\n");
    exit( EXIT_FAILURE );
  }
  FFLUSH_ERROR(fflush(fp)); 
  
  #ifdef DEBUG
  printf("Message send: %s", recv_buf);
  #endif
  //close fifo
  int result = fclose(fp);
  CHECK_FIFOCLOSED(result);
  pthread_mutex_unlock(&fifolock);
}

************* RESULT ************

FILE DESCRIPTORS: 13 open at exit.
==3503== Open file descriptor 13: MYFIFO
==3503==    at 0x4AC5EAB: open (open64.c:48)
==3503==    by 0x4A48195: _IO_file_open (fileops.c:189)
==3503==    by 0x4A48459: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==3503==    by 0x4A3AB0D: __fopen_internal (iofopen.c:75)
==3503==    by 0x4A3AB0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==3503==    by 0x10AF08: fifomanager_read (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503==    by 0x10AADB: run_child (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503==    by 0x10AA87: main (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503== 
==3503== Open file descriptor 12: MYFIFO
==3503==    at 0x4AC5EAB: open (open64.c:48)
==3503==    by 0x4A48195: _IO_file_open (fileops.c:189)
==3503==    by 0x4A48459: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==3503==    by 0x4A3AB0D: __fopen_internal (iofopen.c:75)
==3503==    by 0x4A3AB0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==3503==    by 0x10AF08: fifomanager_read (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503==    by 0x10AADB: run_child (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503==    by 0x10AA87: main (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)

Upvotes: 2

Views: 1313

Answers (1)

Daniel Kleinstein
Daniel Kleinstein

Reputation: 5502

fp = fopen(FIFO_NAME, "r");
...
do
{
    fp = fopen(FIFO_NAME, "r");
    ...
} while (strcmp(recv_buf, "End of logging process\n") != 0);
...

result = fclose(fp);

You are not closing the fps you fopen throughout your do-while loop - only the last one - and you are overriding the first fp you opened.


For future reference: when compiling with -g, valgrind can output very useful debugging information - such as a stacktrace with line numbers that can show where leaked memory was allocated. This can help you find the source of memory leaks very quickly.

Upvotes: 5

Related Questions