Search code examples
iosiphoneobjective-cftpexc-bad-access

EXC_BAD_ACCESS / SIGSEGV when uploading with FTP library on iOS (CFWriteStreamOpen)


I am using FTPHelper to perform basic download/upload FTP functions. I have been getting frequent crashes when using it to upload to my destination. The crashes don't seem to ever occur on the first upload but become more and more likely as I make subesequent calls. Xcode spits out EXC_BAD_ACCESS(code=1, address=0x30) at line 517 of the helper class::

success = CFWriteStreamOpen(writeStream);

I've enabled exception breakpoints and zombies but I'm not seeing anything I can make sense of. Here's a snap of what my stack trace looks like at each crash:

enter image description here

I have been able to recreate this same stack trace with several other FTP libraries (BlackRaccon and FTPManager).

The file being uploaded is a simple one generated from the user's interaction with the UI, meaning it's dynamic based on what the user selects on screen. Here is the code that generates, locally saves, and uploads the file:

//Prepare to write a new file to the device and then upload it
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *putContent = [NSString stringWithFormat:@"V%d\n", (int)(funnySlider.value * -1)];
NSString *writepath = [documentsDirectory stringByAppendingPathComponent:@"foo.dat"];

//if the path exists
if([[NSFileManager defaultManager] fileExistsAtPath:writepath]){

    //Upload the newly created file
    [putContent writeToFile:writepath atomically:NO encoding:NSASCIIStringEncoding error:nil];
    [FTPHelper upload:@"foo.dat"];
}

Some odd things I wanted to highlight as well... Filling foo.dat with lots of mumbo jumbo content to increase its file size makes the app much more stable. It's almost reliable at 100KB+. I also have no crashes when using an iPod Touch 4th Generation (okay, I had ONE but it was after dozens and dozens of test sessions). iPhones and iPads do however. Any ideas on how to fix this or why it might be happening? Should I abandon this mode of uploading?


Solution

  • The issue encountered in the posted question is actually a reported bug in CFFTPStream. I received this information from another posting I made to the Apple dev forums when this post wasn't getting any attention.

    After calling CFWriteStreamCreateWithFTPURL, immediately disable the stream's persistent connections like so:

    CFWriteStreamSetProperty(writeStream, 
                             kCFStreamPropertyFTPAttemptPersistentConnection,
                             kCFBooleanFalse);
    

    More information can be found here in another StackOverflow question I stumbled upon when doing some more research and in the post I made to the dev forums. Hope this helps somebody!