views:

412

answers:

3

Hi, I work on code something like this

... HEADERS ...

int *var;

void child() {
  ... //some work
  free(var);
  exit(EXIT_SUCCESSFUL);
}

int main(void) {
  ...
  //allocate variable
  var = (int *) malloc(N*sizeof(int));
  ... //work with var

  for(int i; i<PROC_COUNT; i++) {
    pid_t child = fork();
    if(pid == 0) {
      child(); //main function of new proces
      break;
    }
    elseif(pid < 0) {
      //there is enormous problem -> kill every proces
      kill(0, SIGTERM);
      waitpid(0, NULL, 0); //wait for children
      free(var);
      exit(EXIT_FAILURE);
    }

  }
  free(var);
  return EXIT_SUCCESS;
}

When process is forked, all variables are cloned too. In regular case all copies of var are freed.

If there is error by fork(), I send signal SIGTERM to all created processes. And I need to write signal handler for SIGTERM which free var and terminate application. However, free() is not signal safe function -- so I shouldn`t call it. But how to free() that variable?

A lot of thanks for your answers...

EDIT: valgrind also shows still reacheable variable:

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks.
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated.
==5928== For counts of detected errors, rerun with: -v
==5928== searching for pointers to 1 not-freed blocks.
==5928== checked 49,164 bytes.
A: 

I may be misunderstanding something, but surely after SIGTERM the whole process will disappear, taking your variable with it?

RichieHindle
+4  A: 

I doubt that you need to. Any OS which supports fork(), will also automatically free allocations from malloc() when a process exits, regardless of how it does so (including termination).

There do exist environments where C programs don't run in processes, and where you have to be very careful what you leave lying around at exit. But those environments aren't POSIX, and won't support fork(). They might not support signals, for that matter. If you're writing for any such unusual environment, check your documentation...

If you want to see a clean valgrind report, then you could have the handler stick an event into the child's event loop (or set a flag and post a semaphore, or whatever), and process the event as a clean exit. That's also what you'd do if your program was an interactive application and you wanted to save the user's data on a SIGTERM, assuming your UI framework didn't already translate SIGTERM into an event for you.

Steve Jessop
So why valgrind shows still reachable memory? (Maybe you`re right and the garbage shown by valgrind is made by wrong type of valgrind meassurment)
iyo
valgrind is trying to warn you that you haven't freed the memory prior to exit. It still gets freed by the OS immediately afterwards. Normally that report from valgrind would make you suspicious that maybe your program lost track of the memory. But in the case of a SIGTERM exit, you can ignore this: you know that you haven't gone through your normal cleanup, so you expect spurious claims of "memory leaks".
Steve Jessop
Okay, thanks.I was wondering if it was possible to correct this problematic thing.Thanks a lot!
iyo
I've added a paragraph that might help, if you do want a clean valgrind report. Depending how your child work is done, though, it might be more trouble than it's worth.
Steve Jessop
A: 

You could use exec to start the child process from main rather than calling the child() function directly. Use a command line argument to notify the child program to do the work in main. Then the child process will be able to cleanup properly.

karunski