Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #26252 > unrolled thread
| Started by | Eric <nospam@nospam.com> |
|---|---|
| First post | 2012-09-12 20:07 +0000 |
| Last post | 2012-09-13 00:14 -0700 |
| Articles | 20 on this page of 36 — 18 participants |
Back to article view | Back to comp.lang.c
Failing Malloc Eric <nospam@nospam.com> - 2012-09-12 20:07 +0000
Re: Failing Malloc Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-09-12 22:12 +0200
Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 14:25 -0700
Re: Failing Malloc Andrew Cooper <andrew@nospam.example.com> - 2012-09-12 21:21 +0100
Re: Failing Malloc Eric <nospam@nospam.com> - 2012-09-12 20:34 +0000
Re: Failing Malloc Paul N <gw7rib@aol.com> - 2012-09-12 13:46 -0700
Re: Failing Malloc Eric <nospam@nospam.com> - 2012-09-13 20:21 +0000
Re: Failing Malloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-09-13 17:31 -0400
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 17:57 -0400
Re: Failing Malloc John Gordon <gordon@panix.com> - 2012-09-12 20:55 +0000
Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 14:33 -0700
Re: Failing Malloc falk@rahul.net (Edward A. Falk) - 2012-09-13 22:43 +0000
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:37 -0400
Re: Failing Malloc Johann Klammer <klammerj@NOSPAM.a1.net> - 2012-09-13 08:57 +0200
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:20 -0400
Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 09:27 +1200
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:56 -0400
Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 10:28 +1200
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 18:57 -0400
Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 16:21 -0700
Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 12:07 +1200
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 13:18 -0400
Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-14 07:37 +1200
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 16:05 -0400
Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-13 14:21 -0700
Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 17:38 -0400
Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-13 14:03 -0700
Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-15 10:01 +1200
Re: Failing Malloc Philip Lantz <prl@canterey.us> - 2012-09-14 02:50 -0700
Re: Failing Malloc Kaz Kylheku <kaz@kylheku.com> - 2012-09-12 21:36 +0000
Re: Failing Malloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-09-12 17:41 -0400
Re: Failing Malloc Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-09-12 16:07 -0600
Re: Failing Malloc "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-09-12 16:03 -0700
Re: Failing Malloc Kenneth Brody <kenbrody@spamcop.net> - 2012-09-12 19:24 -0400
Re: Failing Malloc The Great Firewall of China Blue <chine.bleu@yahoo.com> - 2012-09-12 16:34 -0700
Re: Failing Malloc Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-09-13 00:14 -0700
Page 1 of 2 [1] 2 Next page →
| From | Eric <nospam@nospam.com> |
|---|---|
| Date | 2012-09-12 20:07 +0000 |
| Subject | Failing Malloc |
| Message-ID | <k2qq2i$aba$1@speranza.aioe.org> |
Hi What is a good way to respond to a failed Malloc (returns Null)? I do not want to call Abort or Exit immediately. Thanks
[toc] | [next] | [standalone]
| From | Xavier Roche <xroche@free.fr.NOSPAM.invalid> |
|---|---|
| Date | 2012-09-12 22:12 +0200 |
| Message-ID | <k2qqb1$15m$1@news.httrack.net> |
| In reply to | #26252 |
Le 12/09/2012 22:07, Eric a écrit : > Hi What is a good way to respond to a failed Malloc (returns Null)? I do > not want to call Abort or Exit immediately. IMHO, except for large allocations, failure to allocate can lead to abort() In many cases, if you fail to allocate few bytes with malloc(), continuing is anyway difficult as the next new operator or guard page stack allocation will also lead to road end.
[toc] | [prev] | [next] | [standalone]
| From | William Ahern <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2012-09-12 14:25 -0700 |
| Message-ID | <58b7i9-q9p.ln1@wilbur.25thandClement.com> |
| In reply to | #26253 |
Xavier Roche <xroche@free.fr.nospam.invalid> wrote: > Le 12/09/2012 22:07, Eric a écrit : > > Hi What is a good way to respond to a failed Malloc (returns Null)? I do > > not want to call Abort or Exit immediately. > IMHO, except for large allocations, failure to allocate can lead to abort() > In many cases, if you fail to allocate few bytes with malloc(), > continuing is anyway difficult as the next new operator or guard page > stack allocation will also lead to road end. There's no new operator in C, but maybe this was cross posted. As for stack pages: Outside of a GUI application, I've never seen C code that required additional memory when a malloc call fails. Invariably the error condition bubbles up, unwinding the stack. And outside of a simple command-line tool executing a single discrete operation, bailing on a simple allocation failure is extremely poor quality of service from a software application. Personally, I choose data structures which never require additional memory during manipulation, such as linked lists or non-recursive trees with nodes part of the member objects. That means even under memory exhaustion I can always clean up and return to a steady state.
[toc] | [prev] | [next] | [standalone]
| From | Andrew Cooper <andrew@nospam.example.com> |
|---|---|
| Date | 2012-09-12 21:21 +0100 |
| Message-ID | <L864s.41309$Ax.33657@fx18.am4> |
| In reply to | #26252 |
On 12/09/2012 21:07, Eric wrote: > Hi What is a good way to respond to a failed Malloc (returns Null)? I do > not want to call Abort or Exit immediately. > > Thanks > Well - you should probably try to flush any files which are open, return eternal changes back to defaults (changes to the terminal etc), and find a way of letting your user see, or at least work out why they no longer have a running process. Failing gracefully is a lot more effort than you might imagine at first. ~Andrew
[toc] | [prev] | [next] | [standalone]
| From | Eric <nospam@nospam.com> |
|---|---|
| Date | 2012-09-12 20:34 +0000 |
| Message-ID | <k2qrlc$ea5$1@speranza.aioe.org> |
| In reply to | #26254 |
On Wed, 12 Sep 2012 21:21:02 +0100, Andrew Cooper wrote: > On 12/09/2012 21:07, Eric wrote: >> Hi What is a good way to respond to a failed Malloc (returns Null)? I >> do not want to call Abort or Exit immediately. >> >> Thanks >> >> > Well - you should probably try to flush any files which are open, return > eternal changes back to defaults (changes to the terminal etc), and find > a way of letting your user see, or at least work out why they no longer > have a running process. > > Failing gracefully is a lot more effort than you might imagine at first. Sorry maybe I wasn't too clear. I would like to get the Malloc call to succeed if I redo it. Or get some alternative memory eg from the stack or swop.
[toc] | [prev] | [next] | [standalone]
| From | Paul N <gw7rib@aol.com> |
|---|---|
| Date | 2012-09-12 13:46 -0700 |
| Message-ID | <e95d81dd-908d-42cb-bdd2-893456fe16f3@e29g2000vbm.googlegroups.com> |
| In reply to | #26255 |
On Sep 12, 9:34 pm, Eric <nos...@nospam.com> wrote: > On Wed, 12 Sep 2012 21:21:02 +0100, Andrew Cooper wrote: > > On 12/09/2012 21:07, Eric wrote: > >> Hi What is a good way to respond to a failed Malloc (returns Null)? I > >> do not want to call Abort or Exit immediately. > > >> Thanks > > > Well - you should probably try to flush any files which are open, return > > eternal changes back to defaults (changes to the terminal etc), and find > > a way of letting your user see, or at least work out why they no longer > > have a running process. > > > Failing gracefully is a lot more effort than you might imagine at first. > > Sorry maybe I wasn't too clear. I would like to get the Malloc call to > succeed if I redo it. Or get some alternative memory eg from the stack or > swop. If your program has an alternative way of working which uses less memory (say, for example, a slower method) you could put in a new malloc asking for less memory and see if that works. Or you could allocate more memory than you need early in the program, so you've got a bit already to hand when you run a crucial bit of the program. Or you could tell the user that unfortunately the program can't do what was requested. Getting more memory from the stack seems a little risky, as there are normally less checks whether it worked. Swapping your own program's data out to disk might be a possibility if you keep track of what you have done. Swapping other programs out to disk is system-specific, if you want to try this then other newsgroups will be able to give better help. Hope that helps. Paul.
[toc] | [prev] | [next] | [standalone]
| From | Eric <nospam@nospam.com> |
|---|---|
| Date | 2012-09-13 20:21 +0000 |
| Message-ID | <k2tf88$ki9$1@speranza.aioe.org> |
| In reply to | #26257 |
On Wed, 12 Sep 2012 13:46:51 -0700, Paul N wrote:
> On Sep 12, 9:34 pm, Eric <nos...@nospam.com> wrote:
>> On Wed, 12 Sep 2012 21:21:02 +0100, Andrew Cooper wrote:
>> > On 12/09/2012 21:07, Eric wrote:
>> >> Hi What is a good way to respond to a failed Malloc (returns Null)?
>> >> I do not want to call Abort or Exit immediately.
>>
>> >> Thanks
>>
>> > Well - you should probably try to flush any files which are open,
>> > return eternal changes back to defaults (changes to the terminal
>> > etc), and find a way of letting your user see, or at least work out
>> > why they no longer have a running process.
>>
>> > Failing gracefully is a lot more effort than you might imagine at
>> > first.
>>
>> Sorry maybe I wasn't too clear. I would like to get the Malloc call to
>> succeed if I redo it. Or get some alternative memory eg from the stack
>> or swop.
>
> If your program has an alternative way of working which uses less memory
> (say, for example, a slower method) you could put in a new malloc asking
> for less memory and see if that works. Or you could allocate more memory
> than you need early in the program, so you've got a bit already to hand
> when you run a crucial bit of the program. Or you could tell the user
> that unfortunately the program can't do what was requested.
>
> Getting more memory from the stack seems a little risky, as there are
> normally less checks whether it worked. Swapping your own program's data
> out to disk might be a possibility if you keep track of what you have
> done. Swapping other programs out to disk is system-specific, if you
> want to try this then other newsgroups will be able to give better help.
What I mean is, imagine a very large allocation say 4MB. Maybe that's not
available in one chunk, however 4 seperate 1MB allocations could succeed.
That sort of thing.
By stack I mean essentially a local array, i.e.
func()
{
char buf[1000]; /* <--- example */
/* buf can never be Null */
}
Note, that in this case, Null can never be returned for the array.
Thanks
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-09-13 17:31 -0400 |
| Message-ID | <k2tjc5$244$1@dont-email.me> |
| In reply to | #26310 |
On 9/13/2012 4:21 PM, Eric wrote:
>[...]
> By stack I mean essentially a local array, i.e.
> func()
> {
> char buf[1000]; /* <--- example */
> /* buf can never be Null */
> }
>
> Note, that in this case, Null can never be returned for the array.
Probably works for 1000 chars, probably works for 10000,
but what if you need 10MB? Lots of systems devote only a
limited amount of memory for `auto' variables, and if your
program exceeds the limit it's likely to die even more quickly
than if malloc() returned `NULL' (not `Null'). That's what
Paul N meant by "there are normally less checks whether it
worked:" malloc() tells you when it fails and gives you a
choice about how to proceed, but stack explosion doesn't.
Also, I'm a little worried about that word "returned." If
you intend to have func() return a pointer to buf[] or any
part of it, you're in deep trouble: buf[] ceases to exist as
soon as func() returns, and if a caller tries to use a pointer
to the non-existent buf[] there will be fertilizer on the fan.
--
Eric Sosman
esosman@ieee-dot-org.invalid
"The speed at which the system fails is usually not important."
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-13 17:57 -0400 |
| Message-ID | <505256DA.80605@verizon.net> |
| In reply to | #26310 |
On 09/13/2012 04:21 PM, Eric wrote:
> On Wed, 12 Sep 2012 13:46:51 -0700, Paul N wrote:
...
>> If your program has an alternative way of working which uses less memory
>> (say, for example, a slower method) you could put in a new malloc asking
>> for less memory and see if that works. Or you could allocate more memory
>> than you need early in the program, so you've got a bit already to hand
>> when you run a crucial bit of the program. Or you could tell the user
>> that unfortunately the program can't do what was requested.
>>
>> Getting more memory from the stack seems a little risky, as there are
>> normally less checks whether it worked. Swapping your own program's data
>> out to disk might be a possibility if you keep track of what you have
>> done. Swapping other programs out to disk is system-specific, if you
>> want to try this then other newsgroups will be able to give better help.
>
> What I mean is, imagine a very large allocation say 4MB. Maybe that's not
> available in one chunk, however 4 seperate 1MB allocations could succeed.
> That sort of thing.
Here's code that shows how to do something like that:
#define BLOCK_SIZE 0x40000000
#define NUM_BLOCKS 4
#define BUFFER_SIZE (NUM_BLOCKS * BLOCK_SIZE)
// Note: on many systems the calculation of BUFFERSIZE will overflow
int func(void)
{
void *blocks[NUM_BLOCKS] = {0};
int numb;
blocks[0] = malloc(BUFFER_SIZE);
// Even if the calculation doesn't overflow, the conversion to
// size_t may cause unsigned wrap-around. I'll leave it as an
// exercise for the reader to figure out how to deal with those
// possibilities.
if(blocks[0])
{
for(numb=0; numb<NUM_BLOCKS-1; numb++)
blocks[numb+1] = blocks[numb] + BLOCK_SIZE;
}
else
{
for(numb=0; numb<NUM_BLOCKS && blocks[numb]=malloc(BLOCK_SIZE);
numb++);
}
if(numb == NUM_BLOCKS)
{
// code that works with blocks[];
// the key thing is that this code doesn't care whether or not
// the block of memory pointed at by block[1] immediately
// follows the block pointed at by block[2].
}
else
{
// error handling for insufficient memory
}
while(numb>0)
free(blocks[--numb]);
}
However, if you can write your code to work with 4 smaller blocks, it's
probably best to always allocate 4 blocks, rather than one large one.
> By stack I mean essentially a local array, i.e.
> func()
> {
> char buf[1000]; /* <--- example */
> /* buf can never be Null */
> }
>
> Note, that in this case, Null can never be returned for the array.
OK, that's a different approach. Here's some code that shows how
something like that could be done:
int called(void*); // This function does the actual work.
int caller(void)
{
void *p = malloc(BUFFER_SIZE);
if(p)
return called(p);
else
{
char buf[BUFFER_SIZE];
return called(buf);
}
}
Note: if p is non-null, it's guaranteed to be correctly aligned for any
object type. No such guarantee applies to buf. If called() makes use of
the pointer in any way that requires a special alignment, you need to do
something to make sure that 'buf' is suitably aligned. In C99, you
should declare the parameter of called() as being a pointer to an object
with suitable alignment requirements, and declare buf to be an array of
that same object type. C 2011 adds some new alignment-oriented features
that allow for more exotic ways of achieving that same purpose, but this
is still the most appropriate method to use.
On many systems, the memory pointed at by 'p' comes out of the heap,
while 'buf' resides on the stack, but the C standard doesn't use those
terms, and does not require that such things even exist. The stack and
the heap could be two separate memory pools, or they could be different
ends of the same block of memory; more complicated alternatives exist as
well. If they are from a single block of memory, not having enough heap
for malloc() to succeed could correspond to not having enough stack for
the allocation of buf to occur. If that's the case, the behavior of that
program is undefined, and there's nothing you can do to prevent that,
anticipate that, or deal with it.
[toc] | [prev] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2012-09-12 20:55 +0000 |
| Message-ID | <k2qsrd$9d2$1@reader1.panix.com> |
| In reply to | #26255 |
In <k2qrlc$ea5$1@speranza.aioe.org> Eric <nospam@nospam.com> writes:
> Sorry maybe I wasn't too clear. I would like to get the Malloc call to
> succeed if I redo it. Or get some alternative memory eg from the stack or
> swop.
If malloc is returning null, there isn't a lot you can do.
You can wait a short interval and pray that more memory becomes available
(perhaps some other program just exited, freeing up a lot of memory.)
You can free some memory that your program is using elsewhere.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | William Ahern <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2012-09-12 14:33 -0700 |
| Message-ID | <3mb7i9-q9p.ln1@wilbur.25thandClement.com> |
| In reply to | #26258 |
John Gordon <gordon@panix.com> wrote: > In <k2qrlc$ea5$1@speranza.aioe.org> Eric <nospam@nospam.com> writes: > > Sorry maybe I wasn't too clear. I would like to get the Malloc call to > > succeed if I redo it. Or get some alternative memory eg from the stack > > or swop. > If malloc is returning null, there isn't a lot you can do. > You can wait a short interval and pray that more memory becomes available > (perhaps some other program just exited, freeing up a lot of memory.) > You can free some memory that your program is using elsewhere. Or you could fail that _particular_ operation. Most software is multifaceted. Excepting a command-line tool or something performing a discrete operation, there's rarely a persuasive excuse for an application to abort on allocation failure. Just unwind and fail the particular context effected by the malloc failure, the same way you'd fail if a file couldn't be opened or a passwd failed to authenticate. If you open a web page and it consumes too much memory, don't exit the browser. If a server-side generated web page consumes too much memory, don't exit the web server. If an e-mail client uncompressed a trojan attachment which expands to a terabyte of 0s, don't abort the e-mail client.
[toc] | [prev] | [next] | [standalone]
| From | falk@rahul.net (Edward A. Falk) |
|---|---|
| Date | 2012-09-13 22:43 +0000 |
| Message-ID | <k2tnj8$trh$2@blue-new.rahul.net> |
| In reply to | #26258 |
In article <k2qsrd$9d2$1@reader1.panix.com>, John Gordon <gordon@panix.com> wrote: >In <k2qrlc$ea5$1@speranza.aioe.org> Eric <nospam@nospam.com> writes: > >> Sorry maybe I wasn't too clear. I would like to get the Malloc call to >> succeed if I redo it. Or get some alternative memory eg from the stack or >> swop. > >If malloc is returning null, there isn't a lot you can do. Pretty much this. >You can wait a short interval and pray that more memory becomes available >(perhaps some other program just exited, freeing up a lot of memory.) > >You can free some memory that your program is using elsewhere. This is your best bet. Does your app have an "undo" buffer? If so, flush it. Is it caching anything? Flush the caches. Does the application allow the user to have multiple files or windows opened? If so, abort the operation and suggest to the user that they close any unused windows or files. If those options aren't available to you, you're pretty much boned. Or as other posters have suggested, have an alternative algorithm available that uses less memory, or just fail that particular operation and hope that the user can live with it. -- -Ed Falk, falk@despams.r.us.com http://thespamdiaries.blogspot.com/
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-12 17:37 -0400 |
| Message-ID | <50510086.9010908@verizon.net> |
| In reply to | #26255 |
On 09/12/2012 04:34 PM, Eric wrote: ... > Sorry maybe I wasn't too clear. I would like to get the Malloc call to > succeed if I redo it. Or get some alternative memory eg from the stack or > swop. When it is possible to do something like that (which is seldom the case), it is essential that you have one or more blocks of memory somewhere that you can free(), so that you can retry the malloc() with some chance of having it succeed. Problem: if you allocated those other blocks of memory, you either need to write to them, or you need access to information that has already been written to them. If neither of those are the case, those other blocks should either a) not have been allocated yet or b) should have already been free()d. Therefore, you're going to have to figure out some alternative way of dealing with whatever it is that you allocated those other memory blocks for, an alternative that does not require as much memory. That's the hard part, and is one reason why this approach is seldom used. An example that could come up in my own code (if it were radically re-designed). Several of my programs process one scan of data (13,540 pixels) at a time. Those programs could, instead, have been written to process only one frame of data (10 pixels) at a time. There's some inefficiency to doing so, so it would run a bit slower, but it would also require a lot less memory.
[toc] | [prev] | [next] | [standalone]
| From | Johann Klammer <klammerj@NOSPAM.a1.net> |
|---|---|
| Date | 2012-09-13 08:57 +0200 |
| Message-ID | <505183c6$0$18688$91cee783@newsreader03.highway.telekom.at> |
| In reply to | #26255 |
Eric wrote: > > Sorry maybe I wasn't too clear. I would like to get the Malloc call to > succeed if I redo it. Or get some alternative memory eg from the stack or > swop. Some ideas, most of them difficult to do: Do it like linux kernel... If you are using in-memory caches for various things(file i/o, expensive calculations), you can try reclaiming those. If you hack up your own datastructures, you could serialize those to disk on-demand. Both of these would require you to override the allocation functions at least. Also, your allocator would have to know of all the reclaimable areas. Possibly prioritize things... File caching may fail, other things must succeed. Never tried any of this myself, but it is surely possible...
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-12 17:20 -0400 |
| Message-ID | <5050FC9D.4010608@verizon.net> |
| In reply to | #26252 |
On 09/12/2012 04:07 PM, Eric wrote: > Hi What is a good way to respond to a failed Malloc (returns Null)? I do > not want to call Abort or Exit immediately. That depends entirely upon what your program is doing. There's only one general piece of advice that's applicable: do NOT do anything with that null pointer value other than copying it or comparing it to other pointers. My own code would generate an error message identifying the fact that malloc() failed, along with the name of the function that called it, and the name of the file containing that function. That much is required by the coding standards for the project I'm working on. Everything else I will say about this reflects my own personal requirements. If the failure occurred inside a loop, the error message would indicate the value of the loop index at the time the problem was identified. If the message would otherwise be identical to another message that could be produced in the same block of code, something will be added to it to allow unique identification of the particular call to malloc() that triggered the problem. That function would then clean up anything that it needed to clean up, and then return an error code to the calling function. The calling function would respond to that error code by generating another error message containing the same type of information for the calling function as was described above for the function in which the problem was originally detected. This continues all the way up the call chain to main(), which would generate a final error message before returning EXIT_FAILURE. The net effect is an annotated reverse stack-trace. That information isn't particularly useful when dealing with malloc() failures, but it's part of a general architecture for dealing with error conditions that helps me get a running start on diagnosing the underlying problem. This is a totally inappropriate way of handling error conditions for many contexts, such as interactive GUI programs. However, most of my code exclusively runs inside a batch processing environment, where this is quite a reasonable approach. You need to figure out the right approach for your purposes.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-09-13 09:27 +1200 |
| Message-ID | <abcd17F1taiU1@mid.individual.net> |
| In reply to | #26262 |
On 09/13/12 09:20 AM, James Kuyper wrote: > On 09/12/2012 04:07 PM, Eric wrote: >> Hi What is a good way to respond to a failed Malloc (returns Null)? I do >> not want to call Abort or Exit immediately. > > That depends entirely upon what your program is doing. There's only one > general piece of advice that's applicable: do NOT do anything with that > null pointer value other than copying it or comparing it to other pointers. > > My own code would generate an error message identifying the fact that > malloc() failed, along with the name of the function that called it, and > the name of the file containing that function. That much is required by > the coding standards for the project I'm working on. Everything else I > will say about this reflects my own personal requirements. If the > failure occurred inside a loop, the error message would indicate the > value of the loop index at the time the problem was identified. If the > message would otherwise be identical to another message that could be > produced in the same block of code, something will be added to it to > allow unique identification of the particular call to malloc() that > triggered the problem. That function would then clean up anything that > it needed to clean up, and then return an error code to the calling > function. I can understand this approach on a single use embedded system where such a failure may be repeatable. Do error messages provide any useful data on a multi-user system given the generally random memory usage patterns? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-12 17:56 -0400 |
| Message-ID | <505104F1.6080709@verizon.net> |
| In reply to | #26263 |
On 09/12/2012 05:27 PM, Ian Collins wrote: > On 09/13/12 09:20 AM, James Kuyper wrote: >> On 09/12/2012 04:07 PM, Eric wrote: >>> Hi What is a good way to respond to a failed Malloc (returns Null)? I do >>> not want to call Abort or Exit immediately. >> >> That depends entirely upon what your program is doing. There's only one >> general piece of advice that's applicable: do NOT do anything with that >> null pointer value other than copying it or comparing it to other pointers. >> >> My own code would generate an error message identifying the fact that >> malloc() failed, along with the name of the function that called it, and >> the name of the file containing that function. That much is required by >> the coding standards for the project I'm working on. Everything else I >> will say about this reflects my own personal requirements. If the >> failure occurred inside a loop, the error message would indicate the >> value of the loop index at the time the problem was identified. If the >> message would otherwise be identical to another message that could be >> produced in the same block of code, something will be added to it to >> allow unique identification of the particular call to malloc() that >> triggered the problem. That function would then clean up anything that >> it needed to clean up, and then return an error code to the calling >> function. > > I can understand this approach on a single use embedded system where > such a failure may be repeatable. Do error messages provide any useful > data on a multi-user system given the generally random memory usage > patterns? While the systems my programs normally run on are nominally multi-user, there's one user-id that is used to start the production manager program. All other programs in the production system (including mine) are started by the manager, directly or indirectly, and therefore all run using the same user id. For practical purposes, it's a single-user system (and definitely NOT an embedded one). As I said, for failed malloc() calls the information provided by those error messages is seldom of much use - it's just part of a general framework for error handling that I've found useful. However, most of the problems that come up are data-driven, and are unaffected by the "random memory use patterns" of other programs that might be running at the same time on the same system. For those kinds of problems, I've found it a very useful framework. This is example of how the right way to deal with errors depends very much on the context in which those errors have to be dealt with, which is precisely the point I was making. I was recently assigned to help another group with their work - when it fails, their software provides much less information in the error messages than mine does. I keenly miss that information.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-09-13 10:28 +1200 |
| Message-ID | <abcgjrF1taiU4@mid.individual.net> |
| In reply to | #26269 |
On 09/13/12 09:56 AM, James Kuyper wrote: > On 09/12/2012 05:27 PM, Ian Collins wrote: >> On 09/13/12 09:20 AM, James Kuyper wrote: >>> On 09/12/2012 04:07 PM, Eric wrote: >>>> Hi What is a good way to respond to a failed Malloc (returns Null)? I do >>>> not want to call Abort or Exit immediately. >>> >>> That depends entirely upon what your program is doing. There's only one >>> general piece of advice that's applicable: do NOT do anything with that >>> null pointer value other than copying it or comparing it to other pointers. >>> >>> My own code would generate an error message identifying the fact that >>> malloc() failed, along with the name of the function that called it, and >>> the name of the file containing that function. That much is required by >>> the coding standards for the project I'm working on. Everything else I >>> will say about this reflects my own personal requirements. If the >>> failure occurred inside a loop, the error message would indicate the >>> value of the loop index at the time the problem was identified. If the >>> message would otherwise be identical to another message that could be >>> produced in the same block of code, something will be added to it to >>> allow unique identification of the particular call to malloc() that >>> triggered the problem. That function would then clean up anything that >>> it needed to clean up, and then return an error code to the calling >>> function. >> >> I can understand this approach on a single use embedded system where >> such a failure may be repeatable. Do error messages provide any useful >> data on a multi-user system given the generally random memory usage >> patterns? > > While the systems my programs normally run on are nominally multi-user, > there's one user-id that is used to start the production manager > program. All other programs in the production system (including mine) > are started by the manager, directly or indirectly, and therefore all > run using the same user id. For practical purposes, it's a single-user > system (and definitely NOT an embedded one). > > As I said, for failed malloc() calls the information provided by those > error messages is seldom of much use - it's just part of a general > framework for error handling that I've found useful. However, most of > the problems that come up are data-driven, and are unaffected by the > "random memory use patterns" of other programs that might be running at > the same time on the same system. For those kinds of problems, I've > found it a very useful framework. > > This is example of how the right way to deal with errors depends very > much on the context in which those errors have to be dealt with, which > is precisely the point I was making. > > I was recently assigned to help another group with their work - when it > fails, their software provides much less information in the error > messages than mine does. I keenly miss that information. I understand your pain. I use a similar approach to resource allocation failures to yours in C++ with exceptions that convey file and line number information from the call site. These can ether propagate up or be caught and augmented and re-thrown higher up the stack. I guess I haven't done anything similar in C because it takes more work and lot more discipline! -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-12 18:57 -0400 |
| Message-ID | <50511364.5030408@verizon.net> |
| In reply to | #26274 |
On 09/12/2012 06:28 PM, Ian Collins wrote: ... > I understand your pain. I use a similar approach to resource allocation > failures to yours in C++ with exceptions that convey file and line > number information from the call site. These can ether propagate up or > be caught and augmented and re-thrown higher up the stack. I guess I > haven't done anything similar in C because it takes more work and lot > more discipline! On my new task, I'm actually using C++, and I've been trying to figure out how to make use of exceptions to produce the same kind of error output I get from the my C programs. It's a fantasy, since the new group I'm working with has it's own well-entrenched error handling conventions that would not mix well with my preferred style. However, when I did indulge that fantasy, I found that one key problem was that exceptions discard information about where they came from, as the call stack unwinds. Unless I catch and rethrow around every function call that could throw an exception (including the implicit function calls due to ctors, dtors, and operator overloads), it can't duplicate the information generated by my error messages. If I did catch and rethrow everywhere, it would end up looking very similar to my current C code, which constantly checks for error codes. More than one person has looked at my code and come away with the impression that its primary purpose was error handling. One person even submitted a test plan for a module that triggered every single error message that could be generated by that module, but failed to cover normal processing. I'd hoped to find a way to use C++ exceptions to reduce the error message clutter, but I can't figure out how to do so without a corresponding reduction in the amount of information conveyed by the error messages.
[toc] | [prev] | [next] | [standalone]
| From | William Ahern <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2012-09-12 16:21 -0700 |
| Message-ID | <m0i7i9-noi.ln1@wilbur.25thandClement.com> |
| In reply to | #26277 |
James Kuyper <jameskuyper@verizon.net> wrote: > On 09/12/2012 06:28 PM, Ian Collins wrote: > ... > > I understand your pain. I use a similar approach to resource allocation > > failures to yours in C++ with exceptions that convey file and line > > number information from the call site. These can ether propagate up or > > be caught and augmented and re-thrown higher up the stack. I guess I > > haven't done anything similar in C because it takes more work and lot > > more discipline! > On my new task, I'm actually using C++, and I've been trying to figure > out how to make use of exceptions to produce the same kind of error > output I get from the my C programs. It's a fantasy, since the new group > I'm working with has it's own well-entrenched error handling conventions > that would not mix well with my preferred style. > However, when I did indulge that fantasy, I found that one key problem > was that exceptions discard information about where they came from, as > the call stack unwinds. Unless I catch and rethrow around every function > call that could throw an exception (including the implicit function > calls due to ctors, dtors, and operator overloads), it can't duplicate > the information generated by my error messages. You could use libbfd (used by GDB) to lookup symbols. And putting together** a stack trace is pretty easy, especially given that you're not generating one from a signal handler--crossing the signal trampoline is a PITA. Not ideal, of course. For many reasons. But it can definitely cut down on the code clutter. ** There are libraries to do this, but they either try to do too much, or do too little. And in any event, the hard part is grokking the symbols, thus libbfd. I wrote mine in ~1000 SLoC, but the majority of that is signal-safe implementations of date-time routines (e.g. gmtime) and formatted I/O, as I also had to trace and log from within a signal handler.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web