Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-28127] iOS: TiUIListItemProxy overreleased causing intermittent crashing w/ macOS

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2020-10-02T14:38:26.000+0000
Affected Version/sRelease 9.2.0
Fix Version/sRelease 9.2.1
ComponentsiOS
LabelsengSchedule
ReporterChristopher Williams
AssigneeChristopher Williams
Created2020-09-11T17:22:29.000+0000
Updated2020-10-02T14:38:26.000+0000

Description

Occasionally our unit test suite is crashing due to this issue, but it's always spitting out lots of warnings.
objc[14701]: TiUIListItemProxy object 0x7fdd2a8c4e00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a070000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a04f600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a056c00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a04ca00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a17ec00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a059a00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a1a6000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a1a2400 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a0fc800 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a1a2a00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a1a3400 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a1a3e00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2b959200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2b95e000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2b95e600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2b962000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a8c8800 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a8c3400 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a8c3a00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
objc[14701]: TiUIListItemProxy object 0x7fdd2a8cb000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
So I suppose we're double releasing the proxies?

Attachments

FileDateSize
mocha_2020-09-11-095125_macos-walle.crash2020-09-11T17:21:10.000+0000146435
mocha_2020-09-11-104957_macos-walle.crash2020-09-11T18:03:23.000+0000145383
mocha_2020-09-14-113832_slapchop-macos.crash2020-09-14T18:41:08.000+0000145366
mocha_2020-09-14-113909_slapchop-macos.crash2020-09-14T18:41:08.000+0000148568

Comments

  1. Christopher Williams 2020-09-11

    These positions of the code look awfully suspicious: - https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIListView.m#L376-L382 - https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIListView.m#L1518-L1539 In both cases we have a TiUIListItem and a TiUIListItemProxy linked and ask to release both (in the latter we release the proxy but autorelease the cell). But TiUIListItem's dealloc method seems to release the linked proxy as well.
  2. Hans Knöchel 2020-09-12

    Holy moly! We had some very similar crashes related to list items in the past already - this one is definitely the cause. In both of your snippets, the proxy should deallocate / be GC'd automatically, because it is initialized in the same scope. You can use the "Profiler" mode in Xcode to see if the change causes a new memory leak.
  3. Christopher Williams 2020-09-14

    I am also seeing these in the logs, so presumably TableView suffers from he same sort of issue:
        TiUITableViewSectionProxy object 0x7f9a7c0b2200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c17b600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c1c7600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c04dc00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c184600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c210200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c175000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c147c00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c06d600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c125600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c176000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c0eac00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c16a200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c068600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c1bd800 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c106000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c171a00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c094000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c0b7c00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c179600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7c20dc00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewSectionProxy object 0x7f9a7d966600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7d938c00 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewSectionProxy object 0x7f9a7d86c800 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7d82d200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewSectionProxy object 0x7f9a7b866200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.631Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7b8f5200 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.632Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7b98d800 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.632Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7d930000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.632Z] [INFO] :   objc[46360]: TiUITableViewSectionProxy object 0x7f9a7d935000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.632Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7d97a000 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       [2020-09-14T17:31:56.632Z] [INFO] :   objc[46360]: TiUITableViewRowProxy object 0x7f9a7d98e600 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
       
  4. Vijay Singh 2020-09-15

    Test Case -
       var win = Ti.UI.createWindow({
           backgroundColor: '#fff'
       });
       
       var btn = Ti.UI.createButton({
           title: 'Trigger'
       });
       
       btn.addEventListener('click', function() {
       
       			var myTemplate = {
       				childTemplates: [
       					{
       						type: 'Ti.UI.ImageView',
       						bindId: 'pic',
       						properties: {
       							width: '50', height: '50', left: 0
       						}
       					},
       					{
       						type: 'Ti.UI.Label',
       						bindId: 'info',
       						properties: {
       							color: 'black',
       							font: { fontSize: '20', fontWeight: 'bold' },
       							left: '60', top: 0,
       						}
       					},
       					{
       						type: 'Ti.UI.Label',
       						bindId: 'es_info',
       						properties: {
       							color: 'gray',
       							font: { fontSize: '14' },
       							left: '60', top: '25',
       						}
       					}
       				]
       			},
       			listView = Ti.UI.createListView({
       				templates: { template: myTemplate },
       				defaultItemTemplate: 'template'
       			}),
       			sections = [],
       			fruitSection,
       			fruitDataSet,
       			vegSection,
       			vegDataSet,
       			grainSection,
       			grainDataSet;
       		    window = Ti.UI.createWindow({ backgroundColor: 'green' });
       
       		fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits / Frutas' });
       		fruitDataSet = [
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Apple' }, es_info: { text: 'Manzana' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Banana' }, es_info: { text: 'Banana' }, pic: { image: 'Logo.png' } }
       		];
       		fruitSection.setItems(fruitDataSet);
       		sections.push(fruitSection);
       
       		vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables / Verduras' });
       		vegDataSet = [
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Carrot' }, es_info: { text: 'Zanahoria' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Potato' }, es_info: { text: 'Patata' }, pic: { image: 'Logo.png' } }
       		];
       		vegSection.setItems(vegDataSet);
       		sections.push(vegSection);
       
       		grainSection = Ti.UI.createListSection({ headerTitle: 'Grains / Granos' });
       		grainDataSet = [
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Corn' }, es_info: { text: 'Maiz' }, pic: { image: 'Logo.png' } },
       			{ info: { text: 'Rice' }, es_info: { text: 'Arroz' }, pic: { image: 'Logo.png' } }
       		];
       		grainSection.setItems(grainDataSet);
       		sections.push(grainSection);
       
       		listView.setSections(sections);
       
       		window.addEventListener('focus', function () {
       
       		});
       		listView.addEventListener('itemclick',  function(e){
       			window.close();
       		});
       
       		window.add(listView);
       		window.open();
       });
       
       win.add(btn);
       win.open();
       
  5. Vijay Singh 2020-09-15

    1. I am seeing the overrelease message in Mac app only, not on iOS simulator and no crash. 2. As Hans has mentioned theTiUIListItemProxy and TiUIListItem creation, at given code snippet, are in local scope and it should be released. If we do not release it, memory is leaking. Need to check in detail.
  6. Christopher Williams 2020-09-18

    https://github.com/appcelerator/titanium_mobile/pull/12104
  7. Christopher Williams 2020-09-28

    https://github.com/appcelerator/titanium_mobile/pull/12104
  8. Samir Mohammed 2020-09-29

    FR Passed, waiting on Jenkins build and 9.2.1 build.
  9. Samir Mohammed 2020-10-02

    *Closing ticket*. Fix verified in SDK version 9.2.1.v20201001120538, and 9.3.0.v20201001144501. Unable to see any crashing. *Test and other information can be found at:* https://github.com/appcelerator/titanium_mobile/pull/12104

JSON Source