3

thanks in advance for your attention. I'm writing a simulation program for a project, but I have a deallocation problem with his "skeleton" when I use valgrind.

Program Description: The program iterates until the user stops it with a SIGINT or a SIGTERM. It uses two threads, one to make calculations (collector) and one to handle signals (sighandler).

Once one of the signals arrives the program wait the current iteration to finish and then exit. To do that I used a global integer (status) that get changed by sighandler and that collector checks at the end of each iteration. I used a mutex to protect the variable. This is the code:

void* sighandler(void *arg);
void* collector(void *arg);

int status = 0;
int counter = 0;
pthread_t t_sighand, t_collector;
pthread_mutex_t mtx_status = PTHREAD_MUTEX_INITIALIZER;
sigset_t set;

int main(int argc, char *argv[]) {
  /* Blocking signals */
  sigemptyset(&set);
  sigaddset(&set, SIGUSR1);
  sigaddset(&set, SIGINT);
  sigaddset(&set, SIGTERM);
  pthread_sigmask(SIG_SETMASK, &set, NULL);

  /* Threads creation */
  pthread_create(&t_sighand, NULL, &sighandler, NULL);
  pthread_create(&t_collector, NULL, &collector, NULL);

  /* Waiting threads to end */
  pthread_join(t_collector, NULL);
  pthread_join(t_sighand, NULL);

  exit(EXIT_SUCCESS);
}

void* sighandler(void *arg) {
  int sig;

  /* Waiting signals */
  while(TRUE) {
    sigwait(&set, &sig);
    if( (sig == SIGINT) || (sig == SIGTERM) )   {
      /* Change of status to notify the signal received */
      pthread_mutex_lock(&mtx_status);
        status = -1;
      pthread_mutex_unlock(&mtx_status);
      pthread_exit(NULL);
    }
  }
}

void* collector(void *arg) {
  while(TRUE)   {
    /* Here I'll do all the stuff */
    /* At the end I check to see if I need to stop */
    pthread_mutex_lock(&mtx_status);
      if(status == -1)  {
        pthread_mutex_unlock(&mtx_status);
        pthread_exit(NULL);
      }
    pthread_mutex_unlock(&mtx_status);

    counter++;
  }
}

When I try to run it with valgrind I get this result:

==3293== HEAP SUMMARY:
==3293==     in use at exit: 990 bytes in 4 blocks
==3293==   total heap usage: 7 allocs, 3 frees, 1,290 bytes allocated
==3293== 
==3293== LEAK SUMMARY:
==3293==    definitely lost: 0 bytes in 0 blocks
==3293==    indirectly lost: 0 bytes in 0 blocks
==3293==      possibly lost: 0 bytes in 0 blocks
==3293==    still reachable: 990 bytes in 4 blocks
==3293==         suppressed: 0 bytes in 0 blocks
==3293== Rerun with --leak-check=full to see details of leaked memory
==3293== 
==3293== For counts of detected and suppressed errors, rerun with: -v
==3293== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

I found out that if I remove collector there's no memory leak, but I don't understand where the problem could be in collector. Can you help me? :(

Thanks again for your attention and help in advance!

alk
  • 69,737
  • 10
  • 105
  • 255
Redrus
  • 31
  • 2
  • 2
    I don't see any leak....... – Martin James Nov 08 '15 at 17:42
  • I know that the OS will take care of that memory and there's no problem right now. But still I would like to understand why valgrind sees memory still reachable when it should all be freed. – Redrus Nov 08 '15 at 17:45
  • 1
    total heap usage: 7 allocs, 3 frees, 1,290 bytes allocated → looks like it comes from here. I copy/paste this code and run it with valgrind and get: total heap usage: 7 allocs, 7 frees, 2,214 bytes allocated (after sending a INT signal to it). – hexasoft Nov 08 '15 at 17:59
  • 2
    *technically* you should `pthread_mutex_destroy()` your mutex when your're done with it. On some systems that's a no-op, but it may not be on yours. – EOF Nov 08 '15 at 18:00
  • You did compile using the option `-pthread` and not just `-lpthread`, didn't you? – alk Nov 08 '15 at 18:02
  • OT: I feel the signal disposition is not set up correctly. As how I understand the idea behind the code only the `sighandler()`-thread should be able to receive the three signals in question. The code however does not make sure a signal isn't received by any of the other two threads. – alk Nov 08 '15 at 18:11
  • I'm compiling with -lpthread. And not, it's not the mutex_destroy :( – Redrus Nov 08 '15 at 18:12
  • So what happens if using `-pthread` instead of `-lpthread`? – alk Nov 08 '15 at 18:12
  • Nothing apparently, I get the same result. – Redrus Nov 08 '15 at 18:18
  • About the signals, the point is that I want the signals pending and not delivered, to use sigwait(). – Redrus Nov 08 '15 at 21:41
  • Maybe running valgrind with the `--leak-check=full` option would help – built1n Nov 14 '15 at 18:18

1 Answers1

0

On at least one system I tried (FreeBSD), the Standard I/O buffers use malloc. In particular, the buffer for stdout may be allocated dynamically. I get a squeaky clean valgrind result not until I fclose(stdout) before main() is done.

Jens
  • 69,818
  • 15
  • 125
  • 179