[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSAutoreleasePool issue related to Clang and libobjc2
From: |
Quentin Mathé |
Subject: |
Re: NSAutoreleasePool issue related to Clang and libobjc2 |
Date: |
Sun, 11 Nov 2012 15:21:32 +0100 |
Hi Christopher,
Le 10 nov. 2012 à 03:48, Christopher Armstrong a écrit :
> I'm not sure what the correct solution is - it seems that we should detect
> bad code, but leaving the POISON value in place I think is only going to
> catch the instance where object is returned to the autorelease cache, and the
> NSAutoreleasePool is sent -release again, but before it is re-used i.e.
>
> Pool A allocated
> Start exception handler
> > Pool B allocated
> > Pool B assigned to an instance variable of long-lived object N
> >> Pool C allocated
> >> Throw exception
> Exception caught and handled by stack frame of Pool A
> Pool A -release called
> > Pool A -emptyPool
> > Pool B emptied and deallocated by Pool A and returned to cache
> > Pool C emptied and deallocated by Pool A and returned to cache
> N deallocated
> > -release sent to Pool B (Pool B not re-used yet)
>
> I believe if Pool B had already been re-used *before* there is an attempt by
> other code to release it, the POISON value would not allow this to be
> detected. IMHO, the only safe thing we could do in this -emptyPool method is
> to release the NSAutoreleasePool instances and not return them to the cache
> i.e. we should only use the cache for objects that return themselves to the
> cache in -dealloc.
I agree with your conclusion about not pushing any pool to the cache in
-emptyPool. Unless I misunderstood your explanation, I implemented this
solution in the patch I attached to my previous mail. Does the patch looks
correct to you?
Now the problem I'm stuck on is not the -emptyPool issue. If I apply the patch
I proposed, then I crash again but the backtrace is not the same (the second
backtrace in my initial mail). imo, this is another bug unrelated to the
-emptyPool bug.
I just repasted the second backtrace below for conveniency. If you have any
suggestions how to track it down… I'm interested :-)
Program received signal SIGSEGV, Segmentation fault.
0xb7852346 in objc_test_class_flag (aClass=0x74696c71,
flag=objc_class_flag_hidden_class)
at ./class.h:248
248 return (aClass->info & (unsigned long)flag) == (unsigned
long)flag;
(gdb) bt
#0 0xb7852346 in objc_test_class_flag (aClass=0x74696c71,
flag=objc_class_flag_hidden_class) at ./class.h:248
#1 0xb7852d4b in object_getClass (obj=0x8e9454c) at runtime.c:757
#2 0xb7d5a799 in GSObjCIsInstance (obj=0x8e9454c) at GSObjCRuntime.m:84
#3 0xb7ab3139 in otherTime (other=0x8e9454c) at NSDate.m:109
#4 0xb7ab65c4 in -[NSGDate earlierDate:] (self=0x8624f04, _cmd=0xb7f6da60,
otherDate=0x8e9454c) at NSDate.m:1461
#5 0xb7c2bf6a in -[NSRunLoop runMode:beforeDate:] (self=0x85a1b9c,
_cmd=0xb7f6da40,
mode=0xb7f6d7f0, date=0x8e9454c) at NSRunLoop.m:1269
#6 0xb7c2c40b in -[NSRunLoop runUntilDate:] (self=0x85a1b9c, _cmd=0xb7fd7d58,
date=0x8e9454c) at NSRunLoop.m:1305
#7 0xb7fc5189 in -[UKRunner runTest:onObject:class:] (self=0x8117c4c,
_cmd=0xb7fd7d78,
testSelector=0x8452e70, testObject=0x8e8177c, testClass=0xb5a38fe0) at
UKRunner.m:344
#8 0xb7fc57fe in -[UKRunner runTests:onObject:] (self=0x8117c4c,
_cmd=0xb7fd7e30,
testMethods=0x8e81724, testObject=0x8e81744) at UKRunner.m:470
#9 0xb7fc60e3 in -[UKRunner runTestsInClass:] (self=0x8117c4c,
_cmd=0xb7fd7eb0,
testClass=0xb5a38fe0) at UKRunner.m:522
#10 0xb7fc689e in -[UKRunner runTests:inBundle:principalClass:]
(self=0x8117c4c,
_cmd=0xb7fd7cf0, testClasses=0x846e79c, bundle=0x8130984, principalClass=0x0)
at UKRunner.m:560
#11 0xb7fc2ecb in -[UKRunner runTests:inBundleAtPath:currentDirectory:]
(self=0x8117c4c,
_cmd=0xb7fd7e38, testClasses=0x846e79c, bundlePath=0x812c22c, cwd=0x8117c0c)
at UKRunner.m:145
#12 0xb7fc3d33 in +[UKRunner runTests] (self=0xb7fd7c40, _cmd=0x804b7c0)
at UKRunner.m:190
#13 0x08048977 in main (argc=1, argv=0xbffff814) at main.m:33
Cheers,
Quentin.