LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 01-19-2014, 07:12 AM   #1
kornelix
Member
 
Registered: Oct 2005
Location: Germany
Distribution: Ubuntu
Posts: 58

Rep: Reputation: 24
sbrk() does not work as advertised?


I author a program that uses a great deal of memory to the point where malloc() can fail. I have tried to report this situation to the user with a popup message using xmessage(), but xmessage() fails when memory can no longer be allocated (it apparently does nothing at all). Writing to stdout or stderr still works, but who looks at that anymore?

So I tried releasing memory with malloc_trim() and sbrk(), in the hope that xmessage() would work (the program exits after the xmessage() call and can discard all allocated memory. I just want the message to get out).

malloc_trim() and sbrk() do not help. Monitoring the process seems to be saying that the 6 GB of allocated memory is not being released back to the system, and the program exits with this much memory still allocated.

Is there some other way?

thanks
 
Old 01-19-2014, 04:37 PM   #2
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Maybe you need SEH to handle releasing the previously alocated memory by calling 'free', I'm assuming you're allocating it in smaller chunks than 6GB
 
Old 01-19-2014, 05:32 PM   #3
kornelix
Member
 
Registered: Oct 2005
Location: Germany
Distribution: Ubuntu
Posts: 58

Original Poster
Rep: Reputation: 24
SEH?

To use free() I would have to save an unbounded number of pointers returned by malloc() and free them all
(or more accurately those that had not been free()'ed already).

I am looking for a way to free the memory, just before the program calls xmessage and then exits.
malloc_trim() and sbrk() seem to be a solution but this does not work.

Or some other way to create a popup message that works when the executing program is unable to allocate memory.

The problem with xmessage is that it needs a system() call to create a sub-process:
system("xmessage ran out of memory, will exit")
and that needs malloc() to function.
 
Old 01-19-2014, 06:31 PM   #4
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
If you set up your exception handlers in the right order you could possibly pop up the xmessage() after freeing all allocated memory.
 
Old 01-20-2014, 01:00 AM   #5
kornelix
Member
 
Registered: Oct 2005
Location: Germany
Distribution: Ubuntu
Posts: 58

Original Poster
Rep: Reputation: 24
Kindly re-read my last post.
 
Old 01-20-2014, 05:04 PM   #6
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Sorry, I was under the impression that every malloc()ed block should be free()ed when you were finished with it.
 
Old 01-20-2014, 11:40 PM   #7
kornelix
Member
 
Registered: Oct 2005
Location: Germany
Distribution: Ubuntu
Posts: 58

Original Poster
Rep: Reputation: 24
That is true, of course. The problem is that when malloc() fails, you generally have no record of all prior malloc() calls that have been made and not freed, and unwinding everything that has happened up to the point of failure is arbitrarily complex and pointless - the program has just failed fatally and only needs to exit with a message the user can understand.

I plan to make a malloc() wrapper that adds a prefix in front of all pointers returned to the caller by allocating extra space and returning an offset pointer. The prefix will contain a doubly-linked list of all outstanding malloc() calls that can be easily free()d in a loop. The malloc() wrapper adds a new entry to the list, and the free() wrapper links the previous to the next list entry and then free()s the memory including the prefix.
 
Old 01-21-2014, 04:01 AM   #8
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Yes, it's up to the programmer to keep track of all allocated blocks and free them cleanly on exit, otherwise you're creating a memory leak. The wrapper idea sounds interesting but possibly a little more complex than necessary, a linked list of pointers is a great idea but really won't take up much space and may not be worth allocating the extra space during every malloc(), maybe one allocation up front for the list then for every malloc() you just add the new pointer to the list. I usually find making things more complex than required is a good way to shoot yourself in the foot .. but good luck!
 
Old 01-21-2014, 09:36 AM   #9
kornelix
Member
 
Registered: Oct 2005
Location: Germany
Distribution: Ubuntu
Posts: 58

Original Poster
Rep: Reputation: 24
"Yes, it's up to the programmer to keep track of all allocated blocks and free them cleanly on exit, otherwise you're creating a memory leak."

That is what happens when the plug is not pulled in the middle of everything. Proper recovery is just adding complexity when the only thing that can be done is to exit. Exiting frees the memory anyway - there can be no memory leak.

The space for the links is allocated WITH the caller's memory:
address = malloc(request+extra).
return address+extra to the caller.

when free wrapper is called:
free(address-extra);

The code is done and working. The program can allocate memory until failure and still pop-up a message to the user, which was not possible before.
 
Old 01-21-2014, 11:23 PM   #10
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Yes, for userspace applications you're often safe but exiting doesn't free allocated memory in every case so it's better not to be complacent.
 
Old 01-23-2014, 10:00 AM   #11
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
Really, what you need to be doing here is 'planning ahead.' Determine how much memory your program has to allocate, and reserve, say, 10% of that amount for contengencies. So you have, by your own agreement, "90% to play with." Program your memory allocation routines to tally how much memory has been requested, and to throw an exception if that self-imposed limit has been exceeded. So that the program can gracefully die, or do something else that is reasonable given the circumstances.

In such cases, it is also wise to relegate the actual "worker-bee" activities to a non-interactive child process (not a thread ...) that is spawned and owned by the XWindows (GUI) application, so that the GUI never has to compete for the same memory. The memory-allocations of a GUI are quite unpredictable and sometimes quite large. A memory-intensive activity should be operating in its own virtual memory space, and it should use "self-imposed limits" in the manner just described.

Maybe the process can predict how much memory will be required to successfully carry out a particular portion of its work, maybe gleaning this information by tallying a "high-water mark" from previously completed requests. So that it will not attempt to do what probably can't be done. So that it will emerge from the narrow tunnel, however narrow that tunnel may be, "grimy and covered with soot, having done much of the work but perhaps all of it, but nonetheless graciously: alive, and with its head held high."

A program can't control how much memory it has available. But it should not suffocate, regardless.

Pragmatically speaking, if you actually get to the point where malloc(n) == NULL, you are already dead. You just haven't stopped wiggling yet.

Last edited by sundialsvcs; 01-23-2014 at 10:02 AM.
 
  


Reply

Tags
memory management



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Does the "rolling release" work as advertised? KenJackson Arch 24 07-10-2011 01:29 PM
[SOLVED] awk regex /f[eo]{2}t/ does not work as advertised Telengard Programming 14 07-24-2010 01:43 AM
[SOLVED] ls -d --dereference-command-line-symlink-to-dir does not work as advertised jgombos Linux - General 2 09-03-2009 07:18 AM
Recognized CPU less than advertised cwej Ubuntu 6 04-09-2007 04:08 PM
changing Apache advertised name ddaas Linux - Networking 2 03-20-2006 10:35 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 11:48 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration