I get this error message
The connection to service named com.apple.gamed was interrupted, but
the message was sent over an additional proxy and therefore this proxy
has become invalid.
sometimes when calling
loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
What does it mean?
I'm on iOS 9.3.2
This is the worst possible answer, but it's my own experience with loading matches, I'm sorry to say: sometimes it works, sometimes it doesn't. I've received this error message before, and then had it go away after no code changes at all. Just try again.
Ok now I have more findings. Forget my comment to the other answer.
In my case I got the message when I did not use the #escaping keyword on a closure parameter of a function (using Swift 3 where closures are by default non-escaping). This function was called with a closure that did not refer to self (because it was not needed). However, that function called another function, forwarding the closure.
So in the end my closure ended up without a reference.
I recommend you keep a copy of your block that you use as an argument to loadMatchesWithCompletionHandler. This way the block is not released prematurely.
This also explains why the error occurs just sometimes and not always. It's typical for memory release issues.
Related
I am repeatedly calling URLSessionWebSocketTask.receive. I've tried recursively calling the version with the completion handler, as well as looping over the new async version.
At some point, I'm not receiving any more messages, and I want to cancel the web socket. So I call URLSessionWebSocketTask.cancel(). In the log, I see the message [websocket] Read completed with an error Operation canceled. But the completion handler is never called/the async receive method never returns. This means that the Task I launched to do the receiving never closes.
Why doesn't the completion handler get called when the web socket is cancelled?
Are you actually seeing a leak with the closure-based approach?
I see a leak when using the async version, but if I use the closure-version the URLSessionWebSocketTask-object is freed. I don't get any call to the closure, but for my use case that does not matter.
If I use the delegate on the session I will get a callback when the websocket is closed, but I have to call session.invalidateAndCancel when cleaning up.
I also needed to add [weak self] to the closure since I call my receive-function recursively, capturing self.
I have created an example of my class: https://github.com/ChoadPet/H.264-Decoding
When I build my application with DEBUG configuration everything is working fine, but when I archive RELEASE it's crashing on this line:
let status = VTDecompressionSessionDecodeFrame(session,
sampleBuffer: sampleBuffer,
flags: defaultDecodeFlags,
frameRefcon: nil,
infoFlagsOut: nil)
With Address Sanitizer enable I got this error:
Thread 9: Use of deallocated memory
SUMMARY: AddressSanitizer: heap-use-after-free
(.../Frameworks/libclang_rt.asan_ios_dynamic.dylib:arm64+0x1a1f4) in wrap_memmove
...
(if you need more crash info, let me know)
Without: Thread 12: EXC_BAD_ACCESS (code=1, address=0x107dd0020)
I do understand that there is some memory that was freed and it accesses by VTDecompressionSessionDecodeFrame method, but I can't find any address with hex, and I don't understand how this is working perfectly with the DEBUG build.
Before this method, session and sampleBuffer are successfully created(initialized).
Is there are some project settings I can change to DEBUG configuration which can cause the crash? Or somebody can point me out on a code issue?
Thank you!
Changing Optimization Level for Release archive to the same as for Debug - No Optimization[-Onone] hide the problem, but changing build configuration is not the right way to resolve this kinda problem. Also, the problem was not exactly in sampleBuffer. The problem was in blockBufferOut parameter, which goes into sampleBuffer later. I will update the repo source code, so the community can see changes clearly.
So I had before this logic:
// 1. Creating blockBuffer from `bufferPointer`
localFrame.withUnsafeMutableBufferPointer { bufferPointer in
// I should write everything in this body,
// since bufferPointer would be released after the closure
// and so, it will be released from bufferBlock
}
// 2. I called this method, which is creating `sampleBuffer`
CMSampleBufferCreateReady
// 3. I called this method, which is decode frame with session and sampleBuffer
VTDecompressionSessionDecodeFrame
/*
and on this line, it crashes with EXC_BAD_ACCESS,
because the sample wasn't valid anymore, because
on step 1, bufferPointer only valid inside body closure,
so it's release after block when I created sampleBuffer
and later decode it.
This is even pointed by documentation:
Parameters
body
Closure with an UnsafeMutableBufferPointer parameter that points to the
contiguous storage for the array. If no such storage exists, it is created. If
the body has a return value, that value is also used as the return value for the
withUnsafeMutableBufferPointer(_:) method. The pointer argument is valid only for
the duration of the method’s execution.
*/
Summary: if you operate on bufferPointer, do all operations inside a closure.
Added to the answer provided by #vpoltave, I found using a dispatch queue after the samplebuffer creation used to give me an EXC_BAD_ACCESS error or if you turn on address sanitiser, then it would error out in the com.apple.coremedia.videomediaconverter with Use of deallocated memory. Suggestion is to enqueue the raw data instead of the created buffers. For me the source was a frame in elementary format coming in callbacks.
I'm using libjingle_peerconnection installed with cocoapods. When I receive SDP offer through signaling server from my caller, I'm trying to set this as a remote description, which triggers RTCSessionDescriptionDelegate peerConnection:didSetSessionDescriptionWithError:
with error:
Error Domain=RTCSDPError Code=-1 "(null)" UserInfo={error=Failed to set remote answer sdp: Called in wrong state: STATE_INIT}.
My code is:
- (void)transportChanell:(TransportChannel *)channel didReceivedSignalWithSessionDescription:(NSString *)sessionDescription withType:(NSString *)type {
RTCSessionDescription *remoteDesc = [[RTCSessionDescription alloc] initWithType:#"answer" sdp:sessionDescription];
[_peerConnection setRemoteDescriptionWithDelegate:self sessionDescription:remoteDesc];
}
I've investigated the problem quite a lot and found in webRTC source code the place, as I suppose, this error comes from BadRemoteSdp(type, BadStateErrMsg(state()), err_desc); and all possible states of WebRtcSession are:
STATE_INIT = 0,
STATE_SENTOFFER, // Sent offer, waiting for answer.
STATE_RECEIVEDOFFER, // Received an offer. Need to send answer.
STATE_SENTPRANSWER, // Sent provisional answer. Need to send answer.
STATE_RECEIVEDPRANSWER, // Received provisional answer, waiting for answer.
STATE_INPROGRESS, // Offer/answer exchange completed.
STATE_CLOSED, // Close() was called.
Any suggestions, please, what could I missed in caller or callee side?
The offer seems to be marked as an "answer" according to the error message. It fails because it then expects you to be in the STATE_SENTOFFER state.
If you have created an offer and sent it to the other party, you may have forgotten to call setLocalDescription first. If you did not send an offer from the failing client, the other party should be changed to send an offer instead of an answer.
In the event this helps anyone coming here from Google:
I ran into this problem myself, and it turned out I'd hastily copy-pasted some code from the offerer I'd written. So I was init'ing RTCSessionDescription with type RTCSdpTypeAnswer instead of RTCSdpTypeOffer.
Make sure when allocating your RTCSessionDescription that you're using the right type!
I've built a custom NSURLProtocol which is used by a WebView whilst it browses. But at seemingly random times (between a 20 seconds or a few minutes into browsing) I am getting an EXC_BREAKPOINT and the app stops running in my NSURLProtocol.
The relevant part of my NSURLProtocol is below, it's the last line which is showing the EXC_BREAKPOINT
self.mutableData = NSMutableData(data: data!)
self.response = response
self.client?.URLProtocol(self, didReceiveResponse: response!, cacheStoragePolicy: NSURLCacheStoragePolicy.Allowed)
self.client?.URLProtocol(self, didLoadData: data!)
self.client?.URLProtocolDidFinishLoading(self)
The Xcode error is visible below:
I'm totally bamboozled on this one. Does anyone have an idea what might be causing this, and how to fix it?
Thank you!
Sam
There's not enough context for me to fully understand the code here, much less guess what's wrong, but basically what's happening is that there's a lock (mutex) that has been deallocated, but is still being used somewhere down in the NSURL* stack.
This probably points to something not getting retained properly, but it is anybody's guess what or where. It might even be that your protocol is not getting retained properly, in which case you might be able to fix it by assigning your protocol object to a property on itself until after you call your last delegate method, then nulling it out.
With that said, there's reason to believe that this is a bug in the OS itself, so while you try to work around it, you should also file a bug. It will get duped to the other dozen or so bugs from other people who have asked this same question both here and on the Apple developer forums. :-)
I'm calling an asynchronous function from my controller and I pass to it a reference to an error variable, let's say:
NSError *err=nil;
[self myAsyncTask:&err];
if the controller get deallocated, the err variable does not exist anymore, so the app crash with a BAD_ACCESS error (because the function try to change the value of the err variable). How can I deal with that?
Notice that none of the built-in framework methods use pass by reference error reporting with asynchronous calls - they all use delegation or blocks to communicate error status. Using blocks, your API could be written to be used like:
[self doAsyncTaskWithErrorHandler: ^(NSError *error) {
//Handle error
}];
The method signature could look like
- (void)doAsyncTaskWithErrorHandler:(void (^)(NSError *error))errorHandler;
And in the implementation, where you used to do *error = someError; do something like:
NSError *error = ...;
if (errorHandler) {
errorHandler(error);
}
If I'm not mistaken this isn't really an issue with object lifetime though - if the stack frame is popped before the error is set then the pattern in the question would likely cause a crash as well.
How can I deal with that?
If you have an asynchronous function in process, you have to ensure that any variables that it uses remain valid until that function completes. Objective-C's memory management lends itself nicely to this -- a method like your -myAsyncTask can retain its arguments until it no longer needs them. That way, even if the controller (to use your word) is deallocated, the objects referred to by the variables will remain valid.
Another way to do it is to use a block for the async functionality. Blocks automatically retain the resources that they use, so they effectively solve this problem for you.