10

I'm getting peppered with

*** __NSAutoreleaseNoPool(): Object 0x1961180 of class NSEvent autoreleased with no pool in place - just leaking

warnings during run-time and have no idea what the cause is. Cursory Googles indicate that this is a symbol I can break on with Xcode, but adding it as a symbolic breakpoint via Run>Manage Breakpoints>Add Symbolic Breakpoint, or simply via the breakpoints management window, results in a breakpoint with a - next to it instead of a check, which I take to mean it's a symbol that can't be found.

I've tried adding the symbol "__NSAutoreleaseNoPool" with two underscores, one underscore, and now I'm just feeling stupid. The errors continue to get logged and no breakpoints get hit. Any pointers for breaking on Obj-C symbols or debugging this would be appreciated.

[EDIT: after maybe 10 (10 more, so a couple dozen total, including at least two Xcode restarts) runs I got "Pending breakpoint 9 - "__NSAutoreleaseNoPool" resolved" printed to my console and the breakpoint started working. Is there any way to force a pending breakpoint to actually resolve?]

Tyrus
  • 101
  • 1
  • 4

5 Answers5

25

To actually answer your question, look in NSDebug.h. There you will find a comment of which this is part:

NAME OF ENV. VARIABLE                  DEFAULT  SET TO...
NSDebugEnabled                            NO    "YES"
NSZombieEnabled                           NO    "YES"
NSDeallocateZombies                       NO    "YES"
NSHangOnUncaughtException                 NO    "YES"

and farther down are these comments:

// Functions used as interesting breakpoints in a debugger
// void __NSAutoreleaseNoPool(void *object);
        // Called to log the "Object X of class Y autoreleased with no
        // pool in place - just leaking" message.  If an environment
        // variable named "NSAutoreleaseHaltOnNoPool" is set with string
        // value "YES", the function will automatically break in the
        // debugger (or terminate the process).

// void __NSAutoreleaseFreedObject(void *freedObject);
        // Called when a previously freed object would be released
        // by an autorelease pool.  If an environment variable named
        // "NSAutoreleaseHaltOnFreedObject" is set with string value
        // "YES", the function will automatically break in the debugger
        // (or terminate the process).

So you don't really need to set these breakpoints; just set the appropriate environment variables. You can do the latter either from your e.g. .bashrc or in Xcode 4 you can edit the "Run" section of your "scheme" and set them there -- that's what I do, and it works just fine.

Scott Marks
  • 614
  • 8
  • 17
  • 1
    I find it most useful to leave NSDeallocateZombies to NO. Otherwise, they get deallocated! And then they can't serve their hanging-around-to-be-zombies function. Setting it to YES is a kind of temporary patch if you're totally running out of memory. – Scott Marks Nov 14 '11 at 20:23
5

I have the same issue on setting breakpoint on __NSAutoreleaseNoPool(). I finally successfully set the break point use gdb command. After debugger started, press ctrl+C in debugger console. Use "br __NSAutoreleaseNoPool" to set the break point and restart the debugger.

Suyuan Chang
  • 51
  • 1
  • 2
2

It sounds like you're using Cocoa in a thread somewhere and not wrapping the thread body with an autorelease pool. You probably don't need to use breakpoints to find this. Are you doing any detachNewThreadSelector?

Ken Aspeslagh
  • 11,484
  • 2
  • 36
  • 42
  • The breakpoints did start working eventually (went and unchecked "load symbols lazily" checkbox after this ordeal... it's something I forget with every fresh install; I wish that wasn't the default). The issue seems to be more that the graphics library I'm using (SFML) starts its own run loop inside of my existing run loop when I call its draw and update calls from a timer (doing this so I don't block native UI elements). This confuses Cocoa and the debug, but my memory usage isn't exploding like I'd expect it to, so perhaps this is something I can get away with for this (internal dev tool). – Tyrus May 17 '10 at 16:52
  • This solved the problem for me. Inside the method (selector) that I was calling with performSelectorInBackground I had to wrap the body in an NSAutoreleasePool. – Mark Thistle Aug 10 '10 at 20:56
1

The issue here is simple: You are releasing with no pool in place. This usually happens in command line tools written against Foundation. Simply add the following code to your main(): (Irrelevant parts omitted)

int main (…) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  /// Your code goes here.

  [pool drain]; // This one might not strictly speaking be neccessary.
  [pool release];

   return 0;
}

Edit: If you are not creating a command line tool, chances are you are doing something naughty; but nonetheless: If you have code you invoke before NSApplicationMain(), you need to wrap this in the same basic code, draining and releasing the pool before the invocation of NSApplicationMain.

Williham Totland
  • 28,471
  • 6
  • 52
  • 68
  • While my original question had more to do with breakpoints, I am still tangled in this, as well. Now that I'm actually breaking, I see the following stack, and as you can see, I have an auto release pool around my NSApplicationMain and am still getting NSNoAutoreleasePool errors at runtime, with none of my code (outside of main) being executed: http://not-included.net/gfx/stupid/NSNoAutoReleasePool.png An aside about the auto release pool: why's this necessary? Shouldn't the main run loop's auto release pool handle this? – Tyrus May 16 '10 at 07:53
  • Another breadcrumb, this also prints after every "no pool in place" error. Reverted any recent changes, and it still shows up; I guess I just didn't notice before: >*** attempt to pop an unknown autorelease pool (0x89ac00) – Tyrus May 16 '10 at 08:03
  • Ah. Well, the autoreleasepool should not be around `NSApplicationMain()`. That particular functions handles its own pools. – Williham Totland May 16 '10 at 08:46
  • @Williham Totland: It also does not do any harm. – Ivan Vučica Jul 15 '11 at 11:22
  • @Ivan: It wastes valuable CPU cycles. – Williham Totland Jul 15 '11 at 11:24
  • @Williham Totland: Much less important than loads of autorelease pool created and destroyed continuously in the runloop. And I hope you were just trying to be funny. :) – Ivan Vučica Jul 19 '11 at 09:29
  • @Ivan: Just as every sperm is sacred, every cycle counts. – Williham Totland Jul 19 '11 at 10:10
  • @Williham: ♪ ♫ ♪ If a cycle's wasted, I don't think God minds. ♬ ♩ ♫ – Ivan Vučica Jul 19 '11 at 11:46
  • @Ivan: That does not rhyme, and as such, it is simply not true. :P – Williham Totland Jul 19 '11 at 13:37
  • @Williham: Right back in yo' FACE! ;) – Ivan Vučica Jul 19 '11 at 17:39
  • 1
    @Ivan: Well, this is getting laughably far off topic. :P IMO: Every cycle matters. You disagree. I'm going to have to go with "whatever", deal? – Williham Totland Jul 19 '11 at 18:46
  • You should remove one of the calls: [pool drain] or [pool release], You can't use both. -drain is preferred as it plays nicer with garbage collector turned on (if the gc is off, it'll behave the same as -release). – Mirek Rusin Sep 23 '11 at 14:37
0

I know this is an old thread. Just wanted to share some light on the right solution. The right way to have a breakpoint at _autoreleasenopool is using the breakpoint navigator in xcode.(use the key command+6). In the bottom left portion of the breakpoint navigator click '+' sign and add symbolic breaakpoint. Enter the symbol as objc_autoreleaseNoPool.

DevDude
  • 81
  • 1
  • 7