Uploaded image for project: 'Titanium SDK/CLI'
  1. Titanium SDK/CLI
  2. TIMOB-14697

iOS: layoutChildrenIfNeeded tries to access a deallocated view, causing crash

    Details

    • Type: Bug
    • Status: Closed
    • Priority: High
    • Resolution: Cannot Reproduce
    • Affects Version/s: Release 3.1.1
    • Component/s: iOS
    • Labels:
    • Environment:

      Titanium SDK 3.1.1 GA, iOS 5.x, iOS 6.x

      Description

      Randomly during a fast paced view redraw (a lot of parent.add, a lot of parent.remove) the following crash happens:

      Date/Time:       2013-07-26 10:56:41.571 +0200
      OS Version:      iPhone OS 5.1.1 (9B206)
      Report Version:  104
       
      Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
      Exception Codes: KERN_INVALID_ADDRESS at 0x20000008
      Crashed Thread:  0
       
      Thread 0 name:  Dispatch queue: com.apple.main-thread
      Thread 0 Crashed:
      0   libobjc.A.dylib               	0x333cdf78 objc_msgSend + 16
      1   MyBigApp                    	0x000806d6 -[TiViewProxy layoutChildrenIfNeeded] (TiViewProxy.m:2272)
      2   MyBigApp                    	0x001b2fb8 +[TiLayoutQueue layoutProxy:] (TiLayoutQueue.m:79)
      3   MyBigApp                    	0x001b2dc8 performLayoutRefresh (TiLayoutQueue.m:46)
      4   CoreFoundation                	0x35783a2c __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 8
      5   CoreFoundation                	0x35783692 __CFRunLoopDoTimer + 358
      6   CoreFoundation                	0x35782268 __CFRunLoopRun + 1200
      7   CoreFoundation                	0x3570549e CFRunLoopRunSpecific + 294
      8   CoreFoundation                	0x35705366 CFRunLoopRunInMode + 98
      9   GraphicsServices              	0x334a0432 GSEventRunModal + 130
      10  UIKit                         	0x32eddcce UIApplicationMain + 1074
      11  MyBigApp                    	0x000112ac main (main.m:36)
      12  MyBigApp                    	0x0000d3b8 start + 32
      

      This is in fact on the access to hidden in view.hidden (which is really a call to [view isHidden]) in [TiViewProxy layoutChildrenIfNeeded].

      With NSZombieEnabled we can can in fact see this:

      2013-07-29 15:06:14.545 MyBigApp[878:907] *** -[TiUITableView isHidden]: message sent to deallocated instance 0x1eb01b30
      

      But in the last few hours I saw that exact line on TiUILabelViewProxy, TiUIViewProxy, TiUIActivityIndicatorProxy, so that's not related to the fact that the view is a TableView.

      Anyway that's pretty strange, to understand what's going on I made the app crash with the history of retains and releases logged (Instruments » iOS Simulator » Zombies) and found the following history:

      #	Address	Category	Event Type	RefCt	Timestamp	Size	Responsible Library	Responsible Caller
      0	0x1adb4970	TiUILabel	Malloc	1	00:42.335.257	288	MyBigApp	-[TiViewProxy newView]
      1	0x1adb4970	TiUILabel	Retain	2	00:42.335.273	0	MyBigApp	-[TiProxy setModelDelegate:]
      2	0x1adb4970	TiUILabel	Retain	3	00:42.335.640	0	UIKit	-[UIView(Internal) _addSubview:positioned:relativeTo:]
      3	0x1adb4970	TiUILabel	Retain	4	00:42.335.832	0	QuartzCore	-[CALayer layoutSublayers]
      4	0x1adb4970	TiUILabel	Release	3	00:42.335.832	0	QuartzCore	-[CALayer layoutSublayers]
      5	0x1adb4970	TiUILabel	Release	2	00:42.390.437	0	UIKit	-[UIView(Hierarchy) removeFromSuperview]
      6	0x1adb4970	TiUILabel	Release	1	00:42.391.407	0	MyBigApp	__TiThreadReleaseOnMainThread_block_invoke
      7	0x1adb4970	TiUILabel	Release	0	00:42.391.445	0	MyBigApp	__TiThreadReleaseOnMainThread_block_invoke
      8	0x1adb4970	TiUILabel	Zombie	-1	00:42.394.547	0	MyBigApp	-[TiViewProxy layoutChildrenIfNeeded]
      

      Looks like a race condition to me. The really curious thing is, how can [self viewAttached] at the start of layoutChildrenIfNeeded pass if it has been destroyed?


      Anyway I found a way to workaround this issue by modifying the resulting application directly on XCode: modify the line with view.hidden at Classes/API/TiViewProxy.m line ~2272 into:

      if (!self.parentVisible || view.hidden)
      {
        ...
      }
      

      But we don't want to work on non-vanilla versions of Titanium.

        Attachments

          Activity

            People

            • Assignee:
              ingo Ingo Muschenetz
              Reporter:
              yuchi Pier Paolo Ramon
            • Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Backbone Issue Sync

                • Titanium SDK/CLI <> Titanium Mobile
                  Synced with:
                  TIMOB-17104
                  Sync status:
                  ERROR
                  Last received:
                  Last sent:

                  Git Source Code