discuss-gnustep
[Top][All Lists]
Advanced

[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: Wed, 6 Dec 2017 17:21:52 +0000

> On 6 Dec 2017, at 16:53, Lobron, David <dlobron@akamai.com> wrote:
> 
> 
>>> The line in frame 2 is a NS_ENDHANDLER call, inside of a method called  "- 
>>> (NSDate*) limitDateForMode: (NSString*)mode".  There's no call to abort in 
>>> that code.  I tried stepping line by line, but I did not see any exception 
>>> being thrown here.
>> 
>> _Unwind_Resume is the function that is used to resume stack unwinding after 
>> a cleanup.  It should only be called in Objective-C code at the end of an 
>> @finally block (with no corresponding catch block, just @try { … @throw … } 
>> @finally {}) or as the result of using __attribute__((cleanup)).
>> 
>> I believe that if you are targetting the gnustep runtime prior to 1.7 (or 
>> using a very old version of clang), it will be emitted by clang, but I don’t 
>> remember precisely what the EH ABI looked like before I fixed it (I think it 
>> called objc_exception_throw(), not _Unwind_Resume).
> 
> I'm targeting the gnustep-1.8 in my gnustep-make flags, and all of my own 
> code is being built with -fobjc-runtime=gnustep-1.8.  However, I now see that 
> a few .o files in libobjc2 are being compiled with -fobjc-runtime=gnustep-1.7 
> rather than 1.8.  Could that be the problem?  I've copied those compile 
> commands at the end of this message.  I'm using clang-6.0.0, from llvm-5.0.0, 
> which should be the latest stable version.
> 
>> Please can you use a debug build of libobjc2 (that should prevent tail-call 
>> optimisation) and stick a breakpoint on _Unwind_Resume and see where it’s 
>> called from? 
> 
> Done.  The last few lines of the backtrace look like this:
> 
> #0  _Unwind_Resume (exc=0xa6c82e0) at ../../../src/libgcc/unwind.inc:224
> #1  0x00007ffff6f2851d in -[RadixTree 
> initWithFileDescriptor:symbolParserFunction:context:] (self=<optimized out>, 
> _cmd=<optimized out>, fd=<optimized out>, 
>    parser=0x4d2430 <parsePingTreeSymbol(NSString*, void*)>, 
> context=0x2dee800) at RadixTree.mm:863
> #2  0x00000000004d23e7 in -[PingTreeParser pingTreeWithFile:] 
> (self=0x7fffffffb998, _cmd=<optimized out>, path=0x0) at PingState.mm:305
> 
> RadixTree.mm is a file from my own codebase.  Line 863 of that code is an 
> NS_ENDHANDLER block.  The lines leading up to, and including, line 863 look 
> like this:
> 
>        readTree(self, _root, indexMap);
>        gzclose(_gzFile);
>       _gzFile = 0;
>    } NS_HANDLER {
>        [self release];
>        [localException retain];
>        [pool release];
>        [[localException autorelease] raise];
>    } NS_ENDHANDLER
> 
> I can send a longer excerpt if it would be helpful.  The code itself has been 
> around a long time, and has worked under gcc/gnu runtime for a long time.  
> Also, it's running fine with clang/libobjc2 on a number of similar inputs in 
> other unit tests- it's just this one particular test that triggers the 
> SIGABORT.  
> 
> Is there another debugging step I might take here, or does this output 
> suggest the source of the problem?


I’m not sure why you’re seeing a call to _Unwind_Resume from NS_ENDHANDLER.  It 
looks as if you have some cleanup code in that block that is being run when you 
throw the exception from the -raise method.  Actually, this entire block looks 
fragile and redundant - what happens if you simply delete the entire EH block 
here?  Exception objects are retained / released by the runtime, so don’t need 
special handling to propagate past autoreleasepool boundaries.  

David




reply via email to

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