freeing memory inside a signal handler
Asked Answered
H

4

5

I am writing an API that uses sockets. In the API, I allocate memory for various items. I want to make sure I close the sockets and free the memory in case there is a signal such as Ctrl-C. In researching this, it appears free() is not on the safe function list (man 7 signal) thus, I can't free the memory inside a signal handler. I can close the socket just fine though. Does any have any thoughts on how I can free the memory? Thank you in advance for your time.

Horick answered 26/1, 2012 at 17:30 Comment(2)
Add you planning on surviving from the signal?Dambrosio
No not really. I just wanted to clean up memory and sockets before the failHorick
D
6

Alternatively, don't catch the signal and just let the OS handle the cleanup as it's going to do during process cleanup anyway. You're not releasing any resources that aren't tied directly to the process, so there's no particular need to manually release them.

Dibbuk answered 26/1, 2012 at 17:48 Comment(2)
I think that what you and R said makes good sense. First let the application do all the signal handling (make better sense). I wasn't sure if a SIGINT or SIGSEGV would close the sockets or not. I was concerned that they would leave them open until some time out had occured. Thank you for correcting me.Horick
I've had some bad experiences with resource leaks that were allowed because the process would clean it up on exit. I've seen weird crashes that were tough to explain, and if for no other reason: this makes build maintenance more annoying if you want to require no warnings (whether from the compiler or a static analyzer)Diane
A
5

One technique (others exist too):

  1. Have your program run a main processing loop.
  2. Have your main processing loop check a flag to see if it should "keep running".
  3. Have your signal handler simply set the "keep running" flag to false, but not otherwise terminate the program.
  4. Have your main processing loop do the memory cleanup prior to exiting.

This has the benefit of placing both the allocation and de-allocation in blocks of code which are called with a known sequence. Doing so can be a godsend when dealing with webs of interrelated objects, and there is not going to be race condition between two processing flows trying to mess with the same object.

Assemblage answered 26/1, 2012 at 17:40 Comment(2)
This is a library API, so a main loop is not applicable hereHorick
Since I'm building an application and not a library, this solution is perfect for my problem. Thank you for your answer!Pahari
S
2

Don't free in the handler. Instead, indicate to your program that something needs to be freed. Then, detect that in you program, so you can free from the main context, instead of the signal context.

Sapers answered 26/1, 2012 at 17:39 Comment(0)
H
2

Are you writing a library or an application? If you're writing a library, you have no business installing signal handlers, which would conflict with the calling application. It's the application's business to handle such signals, if it wants to, and then make the appropriate cleanup calls to your library (from outside a signal-handler context).

Of course even if you're writing an application, there's no reason to handle SIGINT to close sockets and free memory. The only reasons to handle the signal are if you don't want to terminate, or if you have unsaved data or shared state (like stuff in shared memory or the filesystem) that needs to be cleaned up before terminating. Freeing memory or closing file descriptors that are used purely by your own process are not tasks you need to perform when exiting.

Haiduk answered 26/1, 2012 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.