如何打破__NSAutoreleaseNoPool

时间:2010-05-15 21:22:17

标签: debugging macos

我很满意

  

*** __NSAutoreleaseNoPool():类NSEvent的对象0x1961180自动释放,没有池到位 - 只是泄漏

运行期间的警告,不知道原因是什么。粗略谷歌表示这是我可以用Xcode打破的符号,但是通过Run>管理断点>添加符号断点,或者只是通过断点管理窗口将其添加为符号断点,导致断点与 - 旁边的 - 而不是检查,我认为它是一个无法找到的符号。

我尝试添加带有两个下划线,一个下划线的符号“__NSAutoreleaseNoPool”,现在我感觉很愚蠢。错误继续被记录,没有断点被击中。任何打破Obj-C符号或调试它的指针都将受到赞赏。

[编辑:大概10(10多个,所以总共几十个,包括至少两个Xcode重启)运行我得到“待断点9 - ”__ NSAutoreleaseNoPool“已解决”打印到我的控制台,断点开始工作。有没有办法强制挂起的断点实际解决?]

5 个答案:

答案 0 :(得分:25)

要真实回答您的问题,请查看NSDebug.h。你会在那里找到一个评论,这是其中的一部分:

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

这些评论更进一步:

// 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).

所以你真的不需要设置这些断点;只需设置适当的环境变量。您可以通过以下方式执行后者: .bashrc或者在Xcode 4中,您可以编辑“方案”的“运行”部分并将其设置在那里 - 这就是我所做的,而且它的工作正常。

答案 1 :(得分:5)

我在__NSAutoreleaseNoPool()上设置断点时遇到了同样的问题。 我终于成功设置了断点使用gdb命令。 调试器启动后,在调试器控制台中按ctrl + C. 使用“br __NSAutoreleaseNoPool”设置断点并重新启动调试器。

答案 2 :(得分:2)

听起来你在一个线程中使用Cocoa并且没有用自动释放池包装线程主体。您可能不需要使用断点来查找它。你在做任何detachNewThreadSelector?

答案 3 :(得分:1)

这里的问题很简单:你发布时没有游泳池。这通常发生在针对Foundation编写的命令行工具中。只需将以下代码添加到main() :(省略不相关的部分)

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;
}

编辑:如果您没有创建命令行工具,那么您可能正在做一些顽皮的事情;但是:如果你有NSApplicationMain()之前调用的代码,你需要将它包装在相同的基本代码中,在调用NSApplicationMain之前排空和释放池。

答案 4 :(得分:0)

我知道这是一个老线程。只想分享正确解决方案的一些亮点。 在_autoreleasenopool上使用断点的正确方法是在xcode中使用断点导航器。(使用键命令+ 6)。 在断点导航器的左下角部分,单击“+”符号并添加符号breaakpoint。输入符号objc_autoreleaseNoPool。