Re: Help DTrace gurus: suggestions for capturing a mis-allocated NSData object on a customer's system
Re: Help DTrace gurus: suggestions for capturing a mis-allocated NSData object on a customer's system
- Subject: Re: Help DTrace gurus: suggestions for capturing a mis-allocated NSData object on a customer's system
- From: James Bucanek <email@hidden>
- Date: Fri, 19 Nov 2010 16:26:47 -0700
Greetings,
I've returned my my debugging adventure with a surprising
discovery. I'll be writing this all up as a bug report later,
but for now I thought I'd throw it out for comment. I know this
has turned into a Cocoa question, but it's still a debugging
issue and this is where the thread started ...
Running with Rich Siegel's suggestion of using valgrind, I
imbedded a copy of valgrind in the bundle of my application[1],
and rewrote my launcher to run my helper tool under the control
of valgrind.
Here's what valgrind (immediately!) found:
==78805== Thread 9:
==78805== Conditional jump or move depends on uninitialised value(s)
==78805== at 0x1002AAD08: -[NSConcreteData dealloc] (in /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation)
==78805== by 0x1000EA4B4: -[InsertPackageNamesOp dealloc] (PackageNames.m:1824)
==78805== by 0x1000EA78E: -[InsertNamesOp dealloc] (PackageNames.m:1885)
==78805== by 0x100AC7830: _dispatch_worker_thread2 (in /usr/lib/libSystem.B.dylib)
==78805== by 0x100AC7167: _pthread_wqthread (in /usr/lib/libSystem.B.dylib)
==78805== by 0x100AC7004: start_wqthread (in /usr/lib/libSystem.B.dylib)
==78805== Uninitialised value was created by a stack allocation
==78805== at 0x1000E4BA7: -[PackageNames readNamePackagesOp] (PackageNames.m:590)
Well, that certainly looks like my NSConcreteData dealloc
problem. But here's the mystery: I have no idea why this isn't working
The problem seems to be that NSConcreteData is accessing, or
trying to do something with, the address of the buffer used to
initialize the NSData object. But the address is a stack frame
automatic, and the NSData object was created with +[NSData
dataWithBytes:length:], which should copy the contents of the
bytes parameter, not hang onto it.
Here's a simplified version of my original code:
typedef struct {
int count;
Record set[kBatchSizeMax];
} RecordBatch;
-(void) readNamePackagesOp
{
while (!eof) {
RecordBatch batch;
batch.count = 0;
while (!eof && batch.count<kBatchSizeMax) {
Record record = <read a record from the file>
batch.set[batch.count++] = record
}
NSData* data = [NSData dataWithBytes:&batch length:offsetof(RecordBatch,set)+sizeof(Record)*batch.count];
InsertNamesOp* insertOp = [[[InsertNamesOp alloc]
initWithBatchData:data] autorelease];
[indexOpsQueue addOperation: insertOp];
}
}
Basically, I'm asking +dataWithBytes:length: to copy the
structure on the stack into a newly allocated block of memory.
For some reason, NSData seems to be keeping the original pointer
and using it again later, long after the stack frame of the
function is gone, randomly corrupting memory or throwing SIGABRTs.
The documentation for +dataWithBytes:length: says nothing about
bytes being a malloc'd block, unlike other NSData constructers
that clearly require malloc'd memory.
Here's all I did to fix the problem:
-(void) readNamePackagesOp
{
while (!eof) {
RecordBatch* batch = malloc(sizeof(RecordBatch));
batch->count = 0;
while (!eof && batch->count<kBatchSizeMax) {
Record record = <read a record from the file>
batch->set[batch->count++] = record
}
NSData* data = [NSData dataWithBytesNoCopy:batch
length:sizeof(RecordBatch) freeWhenDone:YES];
InsertNamesOp* insertOp = [[[InsertNamesOp alloc]
initWithBatchData:data] autorelease];
[indexOpsQueue addOperation: insertOp];
}
}
So unless someone can tell me otherwise, I think this is either
a bug in +[NSData dataWithBytes:length:], or an oversight in the documentation.
James
[1] Embedding valgrind doesn't work. Apparently, the install
path gets compiled into the tool and it can't be moved. So don't
try that, it won't work. :)
James Bucanek
____________________________________________________________________
Author of Professional Xcode 3 ISBN: 9780470525227
<http://www.proxcode3.com/>
and Learn Objective-C for Java Developers ISBN: 9781430223696
<http://objectivec4java.com/>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden