Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing an "Out of Memory" error to file, without memory?

I would like to log and possibly warn the user if the program should run out of memory, allowing them a chance to attempt freeing some (hopefully). While I can preallocate the necessary GUI entities needed to display the situation, my concern is that more basic operations using cstdio such as opening or writing to a file, may not be possible in this situation.

My question is, if a program can no longer dynamically allocate memory at all, is it still possible to use cstdio? Are there any special measures I would need take, such as having the file preopened, or setting it to not use a buffer? Will cstring functions still be able to function? Any other possible obstacles to know about in this type of scenario?

(Warning the user is a luxury in this case, the main objective is to log the error to file, then attempt to rescue relevant data with cstdio, then warn the user, in that order)

like image 325
Anne Quinn Avatar asked Jan 08 '14 09:01

Anne Quinn


1 Answers

The short answer to your question is "probably not" (See this answer: https://stackoverflow.com/a/6743056/789491). There are open source versions of snprintf() that do not use dynamic allocations. I'd use that and mmap(2) to write to your file.

I'm guessing the reason you want to use cstdio is you already have some fancy logging/serialization code that uses cstdio. Given that, I'll keep this solution at a high level for now.

In this case at the beginning I'd allocate a buffer large enough to hold your error message and the recovery data (a la @Retired-Ninja). I'd make the buffer at least the size of one page, though (4096 bytes on my Linux box). I'd also open the log file to which I want to write and mmap(2) that file with the buffer size I desire.

In my out of memory exception handler I'd first free the buffer (in order to give me some memory to work with) and construct the error message in the mmap'd file using the malloc-free version of snprintf. I'd then fsync the file (I did not trace the fsync source code to verify if -- or how much -- memory it allocates but it should be less than cstdio). I'd then close the file, do whatever else you want (GUI handling, etc), and exit.

When my program exits normally, I'd simply delete the log file I created with the mmap.

If the amount of data you're trying to save is large (say larger than a page) and variable, you could simply allocate a buffer of one page and build your log file one page at a time. Or you could do something like this https://stackoverflow.com/a/8704032/789491.

HTH.

--Jason

like image 160
Jason Avatar answered Oct 14 '22 05:10

Jason