Crash in CFReadStreamOpen
Crash in CFReadStreamOpen
- Subject: Crash in CFReadStreamOpen
- From: Benoit Foucher <email@hidden>
- Date: Tue, 26 May 2009 22:42:04 +0200
Hi,
I'm getting an EXC_BAD_ACCESS crash in CFReadSreamOpen and I don't
understand why. The code only fails with OS X 10.5.7. It works fine on
10.5.6. I wonder if this is perhaps because I add the stream to
another thread's run loop from the main thread. However, I didn't see
any mention of this not being thread safe -- on the contrary the
documentation seems to indicate that CF run loop functions are thread
safe... (http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#/
/apple_ref/doc/uid/10000057i-CH16-SW26)
Am I doing something wrong here?
Here's the crash:
0 libSystem.B.dylib 0xffff0269 __spin_lock + 9
(cpu_capabilities.h:234)
1 com.apple.CFNetwork 0x9396893a
CacheEntry::_runLoopSchedule(void*, __CFRunLoop*, __CFString const*) +
38
2 com.apple.CoreFoundation 0x940967b4 CFRunLoopAddSource + 532
3 com.apple.CFNetwork 0x938de974 _CFTypeScheduleOnRunLoop
+ 388
4 com.apple.CFNetwork 0x9395b1b0
Host::scheduleWithRunLoop(__CFRunLoop*, __CFString const*) + 86
5 com.apple.CFNetwork 0x93944805
Schedulables::_SchedulablesScheduleApplierFunction(void const*, void*)
+ 33
6 com.apple.CoreFoundation 0x94028846 CFArrayApplyFunction + 198
7 com.apple.CFNetwork 0x939448e3
Schedulables::schedule(__CFRunLoop*, __CFString const*) + 77
8 com.apple.CFNetwork 0x9393e33b
SocketStream::schedule_NoLock(void const*, __CFRunLoop*, __CFString
const*) + 211
9 com.apple.CFNetwork 0x93940472 SocketStream::open(void
const*, CFStreamError*, unsigned char*) + 338
10 com.apple.CFNetwork 0x939436dc
ReadStreamCallbacks::_open(__CFReadStream*, CFStreamError*, unsigned
char*, void*) + 52
11 com.apple.CoreFoundation 0x940adb5c _CFStreamOpen + 316
12 com.apple.CoreFoundation 0x940add58 CFReadStreamOpen + 152
13 a.out 0x00001eaf main + 427
14 a.out 0x00001bbe start + 54
It can easily be reproduced with the following code (compiled with gcc
main.cpp -framework CoreServices -lpthread):
#include <pthread.h>
#include <CoreServices/CoreServices.h>
CFRunLoopRef runLoop = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void* PosixThreadMainRoutine(void*)
{
runLoop = CFRunLoopGetCurrent();
// Signal main thread
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
// Run the run loop
CFRunLoopSourceContext ctx;
memset(&ctx, 0, sizeof(CFRunLoopSourceContext));
CFRunLoopSourceRef source = CFRunLoopSourceCreate(0, 0, &ctx);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
CFRunLoopRun();
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
CFRelease(source);
}
void streamOpenedCallback(CFReadStreamRef stream, CFStreamEventType
eventType, void *info)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
int
main(int argc, char**)
{
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
pthread_attr_t attr;
pthread_t posixThreadID;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine,
NULL);
pthread_mutex_lock(&mutex);
while(!runLoop) // wait for thread to set runLoop
{
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
while(true)
{
CFStringRef h = CFStringCreateWithCString(NULL, "127.0.0.1",
kCFStringEncodingUTF8);
CFHostRef host = CFHostCreateWithName(NULL, h);
CFRelease(h);
CFReadStreamRef readStream = nil;
CFWriteStreamRef writeStream = nil;
CFStreamCreatePairWithSocketToCFHost(NULL, host, 12345,
&readStream, &writeStream);
CFRelease(host);
CFStreamClientContext ctx = { 0, 0, 0, 0, 0 };
CFOptionFlags events = kCFStreamEventOpenCompleted |
kCFStreamEventErrorOccurred;
CFReadStreamSetClient(readStream, events,
streamOpenedCallback, &ctx);
CFReadStreamScheduleWithRunLoop(readStream, runLoop,
kCFRunLoopDefaultMode);
CFReadStreamOpen(readStream);
do
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex); // Wait for signal from
streamOpenedCallback
pthread_mutex_unlock(&mutex);
}
while(CFReadStreamGetStatus(readStream) <=
kCFStreamStatusOpening);
CFReadStreamUnscheduleFromRunLoop(readStream, runLoop,
kCFRunLoopDefaultMode);
CFReadStreamSetClient(readStream, kCFStreamEventNone, 0, 0);
CFReadStreamClose(readStream);
CFWriteStreamClose(writeStream);
}
}
Cheers,
Benoit.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden