We're getting an EXC_CRASH (SIGTRAP) in our iOS app at CFReadStreamSetProperty kCFStreamPropertyHTTPShouldAutoredirect inside [AudioStreamer openReadStream]. We only see this on iOS 6, but it's consistent across all devices running that version of the OS. If we comment out that line, it doesn't crash but every URL we feed to the AudioStreamer immediately stops after AS_WAITING_FOR_QUEUE_TO_START with no error.
Have you tested the class with iOS 6? Are you aware of any issues? We've done some heavy debugging and are preparing to open an inquiry with Apple. Just thought I'd check here first.
The actual crash itself is inside CoreFoundation, __CFTypeCollectionRetain to be exact. Below is part of the symbolicated report. I can provide you with more details privately, if you're interested.
Date/Time: 2012-11-02 21:32:34.656 -0400
OS Version: iOS 6.0.1 (10A525)
Report Version: 104
Exception Type: EXC_CRASH (SIGTRAP)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread: 1
Thread 0 name: Dispatch queue: com.apple.main-thread
0 CoreFoundation 0x3a9254e0 __CFTypeCollectionRetain + 8
1 CoreFoundation 0x3a88ed6c _CFArrayReplaceValues + 264
2 CoreFoundation 0x3a88ec5a CFArrayAppendValue + 106
3 CFNetwork 0x3353d56a HTTPReadStream::_streamImpl_SetProperty(__CFString const*, void const*) + 462
4 CFNetwork 0x3353d99e non-virtual thunk to HTTPReadStream::_streamImpl_SetProperty(__CFString const*, void const*) + 6
5 CFNetwork 0x3357d1da CoreStreamBase::_streamInterface_SetProperty(__CFString const*, void const*) + 18
6 CFNetwork 0x3357bb4e CoreStreamCFStreamSupport<__CFReadStream*, CoreReadStream>::_stream_setProperty(__CFReadStream*, __CFString const*, void const*, void*) + 6
7 CoreFoundation 0x3a8f491c CFReadStreamSetProperty + 96
I have not tested this with iOS 6 before, so I'm not aware of anything previously. Are you sending the request to a URL which does indeed make a redirect? If you are it kind of makes sense when you comment out the line that it just hangs waiting for more data.
One thing you may want to try is possibly the CFHTTPReadStreamSetRedirectsAutomatically method. It's deprecated, but it may not cause a crash?
I certainly wouldn't mind trying to help you with this if you're willing to share more details.
Forgive me, I should have been more specific.
The URLs do not have a redirect, so setting kCFStreamPropertyHTTPShouldAutoredirect isn't necessary to play the stream.
When commenting out that code, the app no longer crashes but the audio streams never play. It seems that in iOS 6, calling CFReadStreamSetProperty on the stream exposes some kind of issue with the stream itself, which results in a crash. Without CFReadStreamSetProperty, the stream is simply unable to function correctly and fails, but without a specific error. Both the crash and the stream failure are likely manifestations of the same underlying iOS 6-specific issue.
I spoke with someone at Apple who suggested this might be ARC related. Do you happen to have a non-ARC version of the class that we could try out? Would save us the trouble of de-ARC-ifying the codebase.
Hmm, it sounds like there might be two things going on here.
We believe the CFReadStreamSetProperty kCFStreamPropertyHTTPShouldAutoredirect crash is a red herring, and that the real culprit is the CFReadStreamRef itself. What the exact issue is, we do not yet know. But we believe the audio stream fails because of this same issue with the CFReadStreamRef. We can see the HTTP server responding to the request and sending data, and we can also see that data being received by the client on the network stack level. The data, however, is not made available through the CFReadStreamRef.
Again, this only happens when running on iOS 6. It could very well be exposing a CFNetwork-related iOS 6 bug. Although that seems hard to believe because the AudioStreamer code is fairly boilerplate so you'd expect to see this issue being discussed elsewhere. But one never knows.
Our Apple contact suggested looking into ARC as a first step, before opening an official inquiry.
Turns out I misspoke. When the redirect code is commented out, the audio stream fails with the error "Failed to open file stream". It immediately jumps from Waiting for Data to Stopped.
OK, so it looks like my engineer was incorrect. The HTTP request from the app is never made. After some additional debugging, it appears that the AudioStreamer instance loses the url value by the time openReadStream is called. We can see it being set correctly, but then it reverts to nil. Again, this only happens when running on iOS 6.
Have you tried breaking on writes to the instance variable?
We've tried setting a watch on the variable, but that doesn't seem to do the trick.
One detail I forgot to mention, this issue only occurs when running on an actual iPhone w/ iOS 6. If we run the app in the iOS 6 Simulator, everything is fine.
To make matters even more bizarre, we just discovered that if we break on streamWithURL and then step through the method before continuing execution, it works!
To be specific, if we step through the line stream->url = url; in the streamWithURL method, it works. If we break on that line and simply continue execution, it still fails with the url ivar reverting to nil by the time it calls openReadStream.
stream->url = url;
Beyond adding an assertion that the url isn't nil when you pass it into CFHTTPMessageCreateRequest, I can't think of much off hand. If this is definitely a problem where the url is nil by the time is gets passed in, then zeroing in on when it's nil-ified is the first thing to look into.
It's possible that gdb tampers with timings and interleavings, so that's why it may not show up in the debugger and only when running naturally.
We solved it. It turns out that when we ran our code through the Xcode ARC refactoring wizard, it changed the url ivar and property declarations to __weak. Switching it back fixed the problem.
I just want to leave a huge thanks to daegloe! We ran into a similar issue with our app (not using this repo, just using CFNetwork), and you saved me an incalculable amount of time tracking this down. So thanks!