[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Mysterious crash in NSRunLoop, using libobjc2 on Linux

From: David Chisnall
Subject: Re: Mysterious crash in NSRunLoop, using libobjc2 on Linux
Date: Tue, 19 Dec 2017 20:33:36 +0000

> On 19 Dec 2017, at 18:57, Lobron, David <address@hidden> wrote:
> Hey David-
> I've now got a very pruned-down program that reproduces the bug.  However, 
> that program still uses NSException, NSAutoreleasePool, and the 
> NS_DURING/HANDLER/ENDHANDLER macros.  I've tried replacing these with plain 
> @try/@catch and @throw in order to depend only on libobjc2, but so far the 
> latter code hasn't reproduced the bug.  For example, here is some code from 
> my minimal code that reproduces the bug:
> @interface MinRep2 : NSObject {
> }
> - (void)poke;
> @end
> @implementation MinRep2
> - (void)poke {
>  NSAutoreleasePool *pool = [NSAutoreleasePool new];
>    [NSException raise:@"foo" format:@"bar"];
>    [localException retain];
>    [pool release];
>    [[localException autorelease] raise];
>      [pool release];
> }
> @end
> I tried to translate this into code that depends only on libobjc2 as follows 
> (this inherits the Test class in the libobjc2 Test directory):
> @interface MinRep2 : Test {
> }
> - (void)poke;
> @end
> @implementation MinRep2
> - (void)poke {
>  id e1;
>  @try {
>    @throw e1;
>  } @catch (id x) {
>    [x retain];
>    [x autorelease];
>    @throw x;
>  }
> }
> @end
> Am I doing this translation approximately the right way?  The "raise" method 
> in the gnustep-base NSException class does a lot of things, and so it's 
> likely that my call to @throw above might be missing something essential to 
> coercing the ObjC exceptions to and from a C++ one.

This looks mostly correct, though you have removed the autorelease pool calls 
(objc_autoreleasePoolPush() / objc_autoreleasePoolPop()).  The big difference 
is that this looks as if it might be rethrowing, whereas your other code is 
definitely calling another function that is throwing the object again (in a 
different exception object).  This is a bit more interesting, because this is 
the case where you’re in a catch block, but now you’re throwing another 
exception out of it.  This logic might be incorrect in the runtime, because I 
don’t think it’s well tested.  

When we unwind through this stack frame, if it’s in a C++ compilation unit, 
then we should be calling objc_end_catch() in the cleanup, which should be 
deallocating the first exception, decrementing the reference count of the 
object, and then resuming throwing the other object.  It’s entirely possible 
that there’s a bug somewhere there...


reply via email to

[Prev in Thread] Current Thread [Next in Thread]