1 Reply
      Latest reply on Dec 1, 2015 9:56 PM by DSH
      DSH Level 1 Level 1 (0 points)

        Why does this crash?

         

        import Cocoa
        struct Something {
          var timer: dispatch_source_t? = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT)
        }
        var s = Something()
        s.timer = nil // CRASH EXC_BAD_INSTRUCTION
        

         

        And this?

         

        import Cocoa
        struct Something {
          var timer: dispatch_source_t?
        
          init() {
               timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT)
               timer = nil
          }
        }
        let s = Something() // CRASH EXC_BAD_INSTRUCTION
        

         

        There’s lots of related variants I can get to crash – seems setting a property of type dispatch_source_t within a constructor causes EXC_BAD_INSTRUCTION.

        I discovered this in an NSDocument subclass I have that creates a timer, but if reading from file fails and throws and exception, it crashes with EXC_BAD_INSTRUCTION while destroying the document.

         

        Something interesting I found: creating and destroying an unrelated timer seems to stop it crashing?

         

        import Cocoa
        var someOtherUnrelatedTimer: dispatch_source_t? = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT)
        someOtherUnrelatedTimer = nil
        
        struct Something {
          var timer: dispatch_source_t? = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT)
        }
        var s = Something()
        s.timer = nil // Doesn’t crash, when someOtherUnrelatedTimer = nil, above
        

         

        What’s going on here? I’m not just going crazy and missing something, am I?

        Filed rdar://23718983

        • Re: EXC_BAD_INSTRUCTION when deallocating dispatch_source_t from within init()
          DSH Level 1 Level 1 (0 points)

          I just found the answer to my question, in this other thread from a month ago: https://forums.developer.apple.com/message/46175#46175

              dispatch_source_cancel(dispatchSource);
              dispatch_resume(dispatchSource);
          
          

          https://devforums.apple.com/message/1105979#1105979

           

          So, this example does not crash anymore:

           

          import Cocoa
          struct Something {
          
            var timer: dispatch_source_t?
          
            init() {
                 timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT)
                 dispatch_source_cancel(timer!)
                 dispatch_resume(timer!)
                 timer = nil
            }
          }
          let s = Something() // Does not crash anymore
          
          

           

           

          In my original NSDocument subclass that started all this, I have added this in deinit, so if it is destroyed by an exception handler at any point, it will be cleaned up properly.

           

            deinit {
                 if let t = timer {
                      dispatch_source_cancel(t)
                      dispatch_resume(t)
                 }
            }
          
          1 of 1 people found this helpful