EAAcessory errors while closing session with iOS 6.0 GM
Asked Answered
T

3

13

There is a MFI device that is connected to iPhone 4S (6.0 GM) or to iPad (6.0 GM) via Bluetooth (2.1 + EDR). The project was built on Xcode 4.5 GM. When the app gets EAAccessoryDidDisconnectNotification it will send message [_eaSessionController closeSession];. All these worked nice in iOS 5.1.1 or earler. But on iOS6 with this message I got logs as follows:

-[NSCondition dealloc]: condition (<NSCondition: 0x2e5640> '(null)') deallocated while still in use
Break on _NSLockError() to debug.

Any ideas?

Tennes answered 17/9, 2012 at 9:56 Comment(3)
I am in the same situation as you. We have low power bluetooth device which connects and disconnects regularly. When the phone is physically connected to the debugger i get the error in the log if the app is in the background. If im not connected to the debugger it just crashes. Have you filed a bug with apple?Kazim
No, I don't report this problem to Apple. >> "low power bluetooth device" Do you mean "Bluetooth 4.0 low energy" ?Tennes
No its bluetooth 2.1, i think, not the new 4.0. It disconnects and reconnects on its own and i just use the connection notifications to trigger my reading and writing back to it causes it to disconnect.Kazim
T
4

There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:

Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.

There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and iOS 6.0.1:

#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>

@implementation NSCondition (LeakDealloc)

- (void) safeDealloc
{
    float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (sVersion < 6.0 || sVersion >= 6.1)
    {
        [self safeDealloc];
    }
}

+ (void) load 
{
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(safeDealloc)));
}

@end

This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!

Tennes answered 16/11, 2012 at 9:50 Comment(2)
Hi there. I don't have the issue on iOS 6.0.1 at least, but quite the same for iOS 6.1.X. Actually, it crashes on NSRecursiveLock dealloc. My first workaround was "don't set to nil the session when closed". I also tried your solution with a category and it works too. There is an opened post on apple developer forums which mentions this issue, with a bug opened (devforums.apple.com/message/789466#789466). I'm really surprised this bug still exists and that there are not a lot of feedbacks on web. Are we a few people, or doing something wrong with the session?Edwinaedwine
In my case we have a crash only for some unpopular transitional versions.. But all works fine for popular iOS versions. Seems this is it. Please keep us in touch with your bug report status.Tennes
D
4

I came across the same issue. This warning is thrown when calling [NSStream close] upon receiving an EAAccessoryDidDisconnectNotification. There should be also some data exchange between the two devices just before the disconnection.

Breaking on _NSLockError will show that at the moment the object is deallocated, some of the threads spawned by the external accessory framework are waiting on conditions. One of those certainly waits on the condition that is being freed, which explains the warning thrown on the console.

I also noticed that the number of threads created by the external accessory framework keeps on growing each time the accessory disconnects then connects, and they seem to be just leaking.

It seems to me that somehow, the external accessory framework does not properly free the resources it allocates, which results in a lot of mess. One of the subsequent effects of this are crashes that happen inside one of those leaked threads during a call to OSAtomicCompareAndSwap64.

I managed to reproduce the issue using a basic sample in which the streams are scheduled on the main thread to avoid any thread management inside the application. I believe it's an accessory management bug on iOS 6 that Apple should be aware of. I'll report it and wait for what they have to say.

Meanwhile, I wonder if anyone of you guys has managed to make any progress on this.

Thanks,

Demarcate answered 5/10, 2012 at 13:20 Comment(2)
No i havent gotten any further with this. I think ill also file a bug. Hopefully that will help push them to get it fixed quicker. I have however seen the leaked threads issue and started a support ticket for it. They had me file a bug report for it and we sent in a device for them to test on. I was told the other day that they are aware of and understand the problem. They just didn't say if and when it will get fixed. If i were to guess they will probably fix it for iOS 6.Kazim
Thanks Paul for the update. I guess you mean iOS 6.1 since the issue already exist under iOS 6.0 :)Demarcate
T
4

There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:

Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.

There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and iOS 6.0.1:

#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>

@implementation NSCondition (LeakDealloc)

- (void) safeDealloc
{
    float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (sVersion < 6.0 || sVersion >= 6.1)
    {
        [self safeDealloc];
    }
}

+ (void) load 
{
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(safeDealloc)));
}

@end

This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!

Tennes answered 16/11, 2012 at 9:50 Comment(2)
Hi there. I don't have the issue on iOS 6.0.1 at least, but quite the same for iOS 6.1.X. Actually, it crashes on NSRecursiveLock dealloc. My first workaround was "don't set to nil the session when closed". I also tried your solution with a category and it works too. There is an opened post on apple developer forums which mentions this issue, with a bug opened (devforums.apple.com/message/789466#789466). I'm really surprised this bug still exists and that there are not a lot of feedbacks on web. Are we a few people, or doing something wrong with the session?Edwinaedwine
In my case we have a crash only for some unpopular transitional versions.. But all works fine for popular iOS versions. Seems this is it. Please keep us in touch with your bug report status.Tennes
D
1

The issue has been fixed in iOS 6.1. There are no more leaking NSCondition or external accessory threads. Apple seem to having fixed the issue properly.

Demarcate answered 29/1, 2013 at 11:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.