casseopea2 / gperftools

Automatically exported from code.google.com/p/gperftools
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

Ugly message 'allocation failed: 12' but no effect #100

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
My application sometimes prints a lot of 'allocation failed: 12' messages.
(unfortunately not really reproducible)
This message is printed if tcmalloc cannot retrieve fresh memory for it's
central cache. I ask myself the question why do I get hundreds of messages
instead of a 0 return value in malloc? I found out that 12 is errno ENOMEM,
but my application never caught a std::bad_alloc exception which should be
fired by operator new, if malloc cannot allocate memory.

Code from tcmalloc v1.0 (the same in earlier versions):
<code>
// Fetch memory from the system and add to the central cache freelist.
void CentralFreeList::Populate() {
  // Release central list lock while operating on pageheap
  lock_.Unlock();
  const size_t npages = Static::sizemap()->class_to_pages(size_class_);

  Span* span;
  {
    SpinLockHolder h(Static::pageheap_lock());
    span = Static::pageheap()->New(npages);
    if (span) Static::pageheap()->RegisterSizeClass(span, size_class_);
  }
  if (span == NULL) {
    MESSAGE("allocation failed: %d\n", errno);
    lock_.Lock();
    return;
  }
</code>

Maybe handling the situation somehow is better than writing this message to
stderr.

Original issue reported on code.google.com by mirko....@web.de on 30 Jan 2009 at 3:07

GoogleCodeExporter commented 9 years ago
Hmm, I'll look into how important this message is, and if it's safe to suppress.

Original comment by csilv...@gmail.com on 30 Jan 2009 at 11:16

GoogleCodeExporter commented 9 years ago
Looking into this, it seems like if this message is printed, it should be a real
problem, and operator new should be raising a bad_alloc exception.  Is new 
returning
NULL, by any chance?  Or is the program running normally, just with this 
message in it?

Is your program multi-threaded?

If you wanted to, you could add some deubgging printf's into the perftools 
code, to
try to give some insight into what's going on:

1) In FetchFromSpansSafe, in central_freelist.cc, add a MESSAGE after the second
FetchFromSpans to ensure that t is not NULL.

2) In cpp_alloc, MESSAGE the return value from do_malloc.

Debugging remotely is difficult -- we'll do what we can to help, but any 
insight you
can give as to what tcmalloc is doing when it prints these messages, would be 
very
helpful!

Original comment by csilv...@gmail.com on 31 Jan 2009 at 12:25

GoogleCodeExporter commented 9 years ago
Thanks for your fast response. As I said before, a bad_alloc is not fired in our
application. As far as I know 'new' does not return NULL and the program is
multi-threaded.
As soon as I can reproduce the problem in a small example, I let you know. I'll 
stick
to your advice and add debug messages.

Best regards,
Mirko

Original comment by mirko....@web.de on 2 Feb 2009 at 9:01

GoogleCodeExporter commented 9 years ago
Just checking up on this -- I'm looking to make a new release in the new few 
weeks,
and it would be nice to fix this problem if we can.  Have the debug messages 
shown up
anything useful?

Original comment by csilv...@gmail.com on 12 Feb 2009 at 7:38

GoogleCodeExporter commented 9 years ago
I found out that deep down in my application there are places where 
std::bad_alloc is
handled without informing anyone ( -> clean some garbage and continue ).
Unfortunately I cannot reproduce this issue, so I can only tell what my tests 
delivered. 

Most likely the following happened:
1) ENOMEM
2) tcmalloc prints the message
3) malloc returns zero
4) new() fires std::bad_alloc
5) some code catches the exception (I didn't hit the right place with a debug 
message
yet :[ )
6) some garbage is deleted ( most like some small portion )
7) the program continues and goes OOM a few steps later
8) steps 1 to 7 for a few hundred times until the program decides that it is 
nonsense
to continue (of course this decision should be made earlier)
9) abort execution as expected on OOM

So as far as I can see by now, the main problem is that the message can not be
suppressed. It is definitely ok to print such messages for debugging, but a 
normal
binary should not print debug messages on stderr.

Original comment by mirko....@web.de on 12 Feb 2009 at 10:31

GoogleCodeExporter commented 9 years ago
OK, for the next release I'll put an #ifdef around that printf, so it's turned 
off by
default.  I agree printing to stderr is a surprising thing for tcmalloc to be 
doing,
so clients should explicitly ask if they want it.

Original comment by csilv...@gmail.com on 12 Feb 2009 at 11:42

GoogleCodeExporter commented 9 years ago
This should be fixed in perftools 1.1.  To get the printf statements in the 
future,
you will have to compile with -DTCMALLOC_WARNINGS.

Original comment by csilv...@gmail.com on 11 Mar 2009 at 9:19