• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bad EXC_BAD_INSTRUCTION on drawRect call in Swift
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bad EXC_BAD_INSTRUCTION on drawRect call in Swift


  • Subject: Re: Bad EXC_BAD_INSTRUCTION on drawRect call in Swift
  • From: Greg Parker <email@hidden>
  • Date: Mon, 25 Aug 2014 14:16:51 -0700

On Aug 24, 2014, at 12:44 PM, Fritz Anderson <email@hidden> wrote:
> On Aug 22, 2014, at 11:25 PM, Peters, Brandon <email@hidden> wrote:
>> ArnoldTransformer2`@objc ArnoldTransformer2.ATView.drawRect (ArnoldTransformer2.ATView)(C.CGRect) -> () at ATView.swift:
>
> So this is the very end of your drawRect(_:CGRect) method in (am I right?) class ATView, subclass of UIView (I’m guessing iOS because of the use of CGRect, but you really should say so when you ask questions), part of your application ArnoldTransformer2. Yes?
>
>> 0x10000e550:  pushq  %rbp
>> 0x10000e551:  movq   %rsp, %rbp
>> 0x10000e554:  subq   $0x30, %rsp
>
> [Make room for an additional 48 bytes in the stack.]
>
>> 0x10000e558:  leaq   0x10(%rbp), %rax
>> 0x10000e55c:  movsd  (%rax), %xmm0
>> 0x10000e560:  movsd  0x8(%rax), %xmm1
>> 0x10000e565:  movsd  0x10(%rax), %xmm2
>> 0x10000e56a:  movsd  0x18(%rax), %xmm3
>> 0x10000e56f:  movq   %rdi, -0x8(%rbp)
>> 0x10000e573:  movsd  %xmm2, -0x10(%rbp)
>> 0x10000e578:  movsd  %xmm3, -0x18(%rbp)
>> 0x10000e57d:  movsd  %xmm0, -0x20(%rbp)
>> 0x10000e582:  movsd  %xmm1, -0x28(%rbp)
>> 0x10000e587:  callq  0x100018f1a               ; symbol stub for: objc_retain
>> 0x10000e58c:  movsd  -0x20(%rbp), %xmm0
>> 0x10000e591:  movsd  -0x28(%rbp), %xmm1
>> 0x10000e596:  movsd  -0x10(%rbp), %xmm2
>> 0x10000e59b:  movsd  -0x18(%rbp), %xmm3
>> 0x10000e5a0:  movq   -0x8(%rbp), %rdi
>> 0x10000e5a4:  movq   %rax, -0x30(%rbp)
>> 0x10000e5a8:  callq  0x10000bc60               ; ArnoldTransformer2.ATView.drawRect (ArnoldTransformer2.ATView)(C.CGRect) -> () at ATView.swift:224
>
> This instruction is a call to drawRect(_:CGRect). (Attention world: it’s a _direct_ call!) In fact, it looks to be a recursive call to this very function.

It is not. Time for Today's Lesson In Swift's Generated Code!

** Today's Lesson In Swift's Generated Code **
The interface for a pure-Swift function often differs from the interface to the corresponding Objective-C function. For example, Swift may use a different retain/release convention than Objective-C, or Swift may use a closure struct where Objective-C uses a block object, or Swift may use a Swift.String where Objective-C uses an NSString. In such cases the compiler will generate a pure-Swift function plus an additional wrapper for Objective-C's use that translates the parameters and return value appropriately.

The disassembly here is one of those wrapper functions. Note carefully the demangled symbol names:

@objc ArnoldTransformer2.ATView.drawRect (ArnoldTransformer2.ATView)(C.CGRect) -> ()
calls
ArnoldTransformer2.ATView.drawRect (ArnoldTransformer2.ATView)(C.CGRect) -> ()

The first is the Objective-C compatible wrapper function. The second is the Swift function. No recursion or improper calls to -drawRect: here.


Back to the original code:

> if self.contentView!.frame.size.width > photo.size.width {
>     docRect.size.width = self.contentView!.frame.size.width
>     imageLocation.origin.x = (self.contentView!.frame.size.width - photo.size.width) / 2.0
> }


Several of Swift's safety checks turn into EXC_BAD_INSTRUCTION on x86_64. These safety checks include array bounds checks, integer overflow checks, and nil checks. In the code above, my guess is that it is dereferencing the optional self.contentView value and getting nil back.

Alternatively, it's possible that the failure is not actually at that line. The backtrace for check failures sometimes blames the first line of the function no matter where the failure actually was.

(Yes, we have a bug report that these check failures are too hard to debug.)


--
Greg Parker     email@hidden     Runtime Wrangler



_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden


References: 
 >Bad EXC_BAD_INSTRUCTION on drawRect call in Swift (From: "Peters, Brandon" <email@hidden>)
 >Re: Bad EXC_BAD_INSTRUCTION on drawRect call in Swift (From: Fritz Anderson <email@hidden>)

  • Prev by Date: Re: Crash from NSURLConnection if delegate released too soon?
  • Next by Date: Re: Crash from NSURLConnection if delegate released too soon?
  • Previous by thread: Re: Bad EXC_BAD_INSTRUCTION on drawRect call in Swift
  • Next by thread: Swift Threads
  • Index(es):
    • Date
    • Thread