{ "id": "63347", "key": "TIMOB-2715", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "8", "description": "", "name": "Needs more info" }, "resolutiondate": "2012-05-03T15:55:26.000+0000", "created": "2011-04-15T03:27:38.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "crash", "ios", "iphone", "look1", "multi-threading" ], "versions": [], "issuelinks": [], "assignee": { "name": "mculpepper", "key": "mculpepper", "displayName": "Marshall Culpepper", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-16T20:44:15.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "{html}

I'm not sure exactly what is going on, but there appear to be\nsome multithreading issues in Titanium.

\n

I've looked at the code, and based on where Titanium actually\ncalls postNotification, it appears only to occur on window close. I\nhave a callback on 'pause' but nothing on window close which means\nit's even more likely to be a Titanium problem.

\n

Here is the contents of the crash log:

\n

Thu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161]\n: [ERROR] The application has crashed with an\nunhandled exception. Stack trace:
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n0 CoreFoundation 0x33ac0975 exceptionPreprocess + 96
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n1 libobjc.A.dylib 0x3347b49d objc_exception_throw + 24
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n2 CoreFoundation 0x33ac030b
\nNSFastEnumerationMutationHandler + 214
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n3 libobjc.A.dylib 0x3348148d objc_enumerationMutation + 24
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n4 My Hood 0x000677e9 0x0 + 423913
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n5 My Hood 0x00067477 0x0 + 423031
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n6 Foundation 0x3362d623 nsnote_callback + 142
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n7 CoreFoundation 0x33a47123 __CFXNotificationPost_old + 402
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n8 CoreFoundation 0x33a46dc3
CFXNotificationPostNotification +\n118
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n9 Foundation 0x33623f8b -[NSNotificationCenter postNotification:] +\n138
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n10 My Hood 0x0001b157 0x0 + 110935
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n11 Foundation 0x33639dfd NSFireDelayedPerform + 368
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n12 CoreFoundation 0x33a770a3
\nCFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION +\n14
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n13 CoreFoundation 0x33a76b5b
CFRunLoopDoTimer + 850
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n14 CoreFoundation 0x33a481b5 CFRunLoopRun + 1088
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n15 CoreFoundation 0x33a47c87 CFRunLoopRunSpecific + 230
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n16 CoreFoundation 0x33a47b8f CFRunLoopRunInMode + 58
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n17 GraphicsServices 0x33b0e4ab GSEventRunModal + 114
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n18 GraphicsServices 0x33b0e557 GSEventRun + 62
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n19 UIKit 0x32099329 -[UIApplication _run] + 412
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n20 UIKit 0x32096e93 UIApplicationMain + 670
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n21 My Hood 0x000041e3 0x0 + 16867
\nThu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161] :\n22 My Hood 0x00003d2c 0x0 + 15660
\nThu Dec 30 22:14:35 unknown My Hood[161] :
Terminating\napp due to uncaught exception 'NSGenericException', reason: '\nCollection <NSArrayM: 0x367560> was mutated while being\nenumerated.(

\n
\n    \"<ListenerEntry: 0x367540>\",\n    \"<ListenerEntry: 0x67edd80>\",\n    \"<ListenerEntry: 0x67f7b20>\"\n)'\n*** Call stack at first throw:\n(\n    0   CoreFoundation                      0x33ac0987 __exceptionPreprocess + 114\n    1   libobjc.A.dylib                     0x3347b49d objc_exception_throw + 24\n    2   CoreFoundation                      0x33ac030b __NSFastEnumerationMutationHandler + 214\n    3   libobjc.A.dylib                     0x3348148d objc_enumerationMutation + 24\n    4   My Hood                             0x000677e9 0x0 + 423913\n    5   My Hood                             0x00067477 0x0 + 423031\n    6   Foundation                          0x3362d623 _nsnote_callback + 142\n    7   CoreFoundation                      0x33a47123 __CFXNotificationPost_old + 402\n    8   CoreFoundation                      0x33a46dc3 _CFXNotificationPostNotification + 118\n    9   Foundation                          0x33623f8b -[NSNotificationCenter postNotification:] + 138\n    10  My Hood                             0x0001b157 0x0 + 110935\n    11  Foundation                          0x33639dfd __NSFireDelayedPerform + 368\n    12  CoreFoundation                      0x33a770a3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14\n    13  CoreFoundation                      0x33a76b5b __CFRunLoopDoTimer + 850\n    14  CoreFoundation                      0x33a481b5 __CFRunLoopRun + 1088\n    15  CoreFoundation                      0x33a47c87 CFRunLoopRunSpecific + 230\n    16  CoreFoundation                      0x33a47b8f CFRunLoopRunInMode + 58\n    17  GraphicsServices                    0x33b0e4ab GSEventRunModal + 114\n    18  GraphicsServices                    0x33b0e557 GSEventRun + 62\n    19  UIKit                               0x32099329 -[UIApplication _run] + 412\n    20  UIKit                               0x32096e93 UIApplicationMain + 670\n    21  My Hood                             0x000041e3 0x0 + 16867\n    22  My Hood                             0x00003d2c 0x0 + 15660\n)\n
\n

Thu Dec 30 22:14:35 unknown UIKitApplication:myhood[0x239e][161]\n: terminate called after throwing an instance of 'NSException'
\nThu Dec 30 22:14:36 unknown ReportCrash[172] : Formulating crash\nreport for process My Hood[161]
\nThu Dec 30 22:14:36 unknown com.apple.launchd[1] :\n(UIKitApplication:myhood[0x239e]) Job appears to have crashed:\nAbort trap
\nThu Dec 30 22:14:36 unknown SpringBoard[29] : Application 'My Hood'\nexited abnormally with signal 6: Abort trap
\nThu Dec 30 22:14:36 unknown ReportCrash[172] : Saved crashreport to\n/var/mobile/Library/Logs/CrashReporter/My\nHood_2010-12-30-221435_Lukass-iPhone.plist using uid: 0 gid: 0,\nsynthetic_euid: 501 egid: 0

{html}", "attachment": [ { "id": "18194", "filename": "thread_analysis.patch", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:39.000+0000", "size": 13311, "mimeType": "text/plain" } ], "flagged": false, "summary": "Collection <__NSArrayM: 0x367560> was mutated while being enumerated", "creator": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "129247", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

The location of the exception is in AppModule.m:92:

\n

-(void)removeEventListener:(NSArray*)args {

\n
\nNSString *type = [args objectAtIndex:0];\nid listener = [args objectAtIndex:1];\n\nListenerEntry *entry = nil;\n\nNSMutableArray *l = [appListeners objectForKey:type];\n\nBOOL needsScanning;\ndo\n{\n    needsScanning = NO;\n
\n

-->>>>>>> for (entry in l) //The fast\niteration is blindly fast when l is nil or count.

\n
\n    {\n        if ([listener isEqual:[entry listener]]) //NSNumber does the right thing with this too.\n        {\n            [l removeObject:entry]; //It's safe to modify the array as long as you break right after.\n            needsScanning = [l count]>0;\n            break;\n        }\n    }\n} while (needsScanning);\n\nif ([appListeners count]==0)\n{\n    RELEASE_TO_NIL(appListeners);\n}\n\n[[self _host] removeListener:listener context:pageContext];\n
\n

}

\n

After being called from line 271:

\n

-(void)willShutdownContext:(NSNotification*)note {

\n
\n// we have to check and see if this context has any listeners\n// that are registered at the global scope and that haven't been\n// removed and if so, we need to remove them since their context\n// is toast.\nif (appListeners!=nil)\n{\n    NSMutableArray *found = [NSMutableArray array];\n    id context = [note object];\n    for (NSString *type in appListeners)\n    {\n        for (ListenerEntry *entry in [appListeners objectForKey:type])\n        {\n            if ([entry context] == context)\n            {\n                id listener = [entry listener];\n                if ([listener isKindOfClass:[KrollCallback class]])\n                {\n                    [found addObject:[NSArray\n                                      arrayWithObjects:((KrollCallback*)listener).type,listener,nil]];\n                }\n                else \n                {\n                    [found addObject:[NSArray\n                                   arrayWithObjects:[entry type],listener,nil]];\n                }\n            }\n        }\n    }\n    if ([found count]>0)\n    {\n        for (NSArray *a in found)\n        {\n
\n

---->>>>>> [self removeEventListener:a];

\n
\n        }\n    }\n}\n
\n

}

{html}", "updateAuthor": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:39.000+0000", "updated": "2011-04-15T03:27:39.000+0000" }, { "id": "129248", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

I suspect the comment:

\n

//It's safe to modify the array as long as you break right\nafter.

\n

A few lines below the crash is incorrect, as the break only\nbreaks out of that block in the for and then as soon as it goes to\nthe next item, the crash occurs. Was the code expecting to break\nout of the overall loop completely?

{html}", "updateAuthor": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:39.000+0000", "updated": "2011-04-15T03:27:39.000+0000" }, { "id": "129249", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Done some further checking, and it doesn't appear to be the line\nI thought (I changed the code, rebuilt the SDK and still crashes).\nI think there's some kind of memory corruption going on in the app\ndue to the number of windows being opened. It opens up lots of\nwindows and closes them again. Eventually the app crashes.

{html}", "updateAuthor": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:40.000+0000", "updated": "2011-04-15T03:27:40.000+0000" }, { "id": "129250", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

OK, I've spent a few more hours debugging this problem.

\n

I'm attaching a patch which DOES NOT fix the problem.\nHowever it makes it happen a lot less frequently. Some things I\nobserved.

\n

First, my app has many windows and sends some global messages,\none of which is 'show_indicator'. This is listened for most of the\nwindows I open, and then subsequently close.

\n

The crashes always occur as above with type set to\n'show_indicator'.

\n

So in my patch I've added a semaphore around the appListeners\nNSMutableDictionary throughout AppModule.m. This doesn't help at\nall, as now the app hangs on the lock statement in\nremoveEventListener. There are no other threads obviously holding\nthe lock, so not sure where it is being taken (my XCode debugging\nfu is not strong enough, clearly).

\n

So finally I added some warn logging statements to the whole\nthing before each action. Suddenly the problem occurs much less\nfrequently. But there is still a semaphore problem as this stack\ntrace (using my new version of the 1.5.1 module which I've dubbed\n1.5.22) shows.

\n
\n   #0    0x33b5d2c4 in semaphore_wait_signal_trap\n   #1   0x33b8ab40 in semaphore_wait_signal\n   #2   0x33b5f0d6 in pthread_mutex_lock\n   #3   0x001422fc in TI::TiLock::lock at TiLock.cpp:88\n   #4   0x00142354 in TI::TiLock::TiLock at TiLock.cpp:72\n   #5   0x0014e454 in TI::TiValue::strictEqual at TiCore:174\n   #6   0x0014e454 in TiValueIsStrictEqual\n   #7   0x0002a712 in -[KrollCallback isEqual:] at KrollCallback.m:94\n   #8   0x0009de40 in -[AppModule removeEventListener:] at AppModule.m:107\n   #9   0x0009f5c6 in -[AppModule willShutdownContext:] at AppModule.m:305\n   #10  0x3362d622 in _nsnote_callback\n   #11  0x33a47122 in __CFXNotificationPost_old\n   #12  0x33a46dc2 in _CFXNotificationPostNotification\n   #13  0x33623f8a in -[NSNotificationCenter postNotification:]\n   #14  0x000276f4 in -[KrollBridge shutdown:] at KrollBridge.mm:429\n   #15  0x33639dfc in __NSFireDelayedPerform\n   #16  0x33a770a2 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__\n   #17  0x33a76b5a in __CFRunLoopDoTimer\n   #18  0x33a481b4 in __CFRunLoopRun\n   #19  0x33a47c86 in CFRunLoopRunSpecific\n   #20  0x33a47b8e in CFRunLoopRunInMode\n   #21  0x33b0e4aa in GSEventRunModal\n   #22  0x33b0e556 in GSEventRun\n   #23  0x32099328 in -[UIApplication _run]\n   #24  0x32096e92 in UIApplicationMain\n
\n

I'm a bit at a loss as to what is going wrong, but hopefully\nthis give you a lot more to go on.

{html}", "updateAuthor": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:40.000+0000", "updated": "2011-04-15T03:27:40.000+0000" }, { "id": "129251", "author": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

And now the patch which it wouldn't let me upload (could be a\nChrome bug).

{html}", "updateAuthor": { "name": "lukaso", "key": "lukaso", "displayName": "lukaso", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:27:40.000+0000", "updated": "2011-04-15T03:27:40.000+0000" }, { "id": "193640", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Ticket does not include a sample case and we cannot evaluate/include source code without a signed CLA on behalf of the submitter.", "updateAuthor": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-05-03T15:55:26.000+0000", "updated": "2012-05-03T15:55:26.000+0000" }, { "id": "412939", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as the information that was requested was never provided.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-16T20:44:15.000+0000", "updated": "2017-03-16T20:44:15.000+0000" } ], "maxResults": 7, "total": 7, "startAt": 0 } } }