On MacOS, we have an agent that implements ARC and that will make some requests to the server each 10 or 15 seconds depending on the user's settings and was working without any problems for almost a year, and just a couple of weeks ago the application crashed in one computer with a Bad access error, specifically on this line:
[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
The Mac OS X version of the machine that is causing problems is 10.7.5, however in other computers with the same OS version is working just fine.
We are using synchronous requests since that is what we need to do the work, however we spent some time making the calls asynchronous but the problem persists.
So, after looking at other posts we added a cache policy: [request setCachePolicy: NSURLRequestReloadIgnoringCacheData]; to avoid any problem with a cache request. The application does run better but is still crashing usually between 1500 - 1800 iterations (30-40 minutes), before it was crashing from between 15 or 20 iterations.
By looking on another questions in stack overflow we tried fix this by using ASIHTTPRequest but again the problem happened randomly (it could crash in the iteration #2 or #123x... as well).
Before the error appears, the request is always working properly, we are getting the data and able to work with it normally.
With NSZombieEnabled option enabled we are not getting any message when the application crashes, try/catch block is not working for us either since the error is pointing to the specific line from above;
[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error]
This is the code that we have to make the request using NSURLConnection:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
init]; [request setHTTPMethod:@"GET"]; [request setURL:[NSURL
URLWithString:url]]; [request setTimeoutInterval: TIMEOUT];
[request setCachePolicy: NSURLRequestReloadIgnoringCacheData];
NSString *authenticationHeader = [NSString
stringWithFormat:@"Basic %@", credentials]; [request
addValue:authenticationHeader
forHTTPHeaderField:@"Authorization"];
NSError *error = nil; NSHTTPURLResponse *responseCode = nil;
NSData *responseData = nil; responseData = [NSURLConnection
sendSynchronousRequest:request returningResponse:&responseCode
error:&error];
if([responseCode statusCode] != 200){ *hasError =[NSString
stringWithFormat: @"Error getting %@, HTTP status code %li",
[responseCode statusCode]]; return @"";
}
}
return [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
And this is the code for ASIHttpRequest:
(NSString *)getDataFromURL: (NSString *)urlString withB64Credentials:(NSString *)credentials error:(NSString **)hasError
{
NSString *response = @"";
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCachePolicy:ASIDoNotReadFromCacheCachePolicy];
[request setTimeOutSeconds:TIMEOUT];
NSString *authenticationHeader = [NSString stringWithFormat:@"Basic %@", credentials];
[request addRequestHeader:@"Authorization" value:authenticationHeader];
[request startSynchronous];
NSError *error = [request error];
if (!error)
response = [request responseString];
else
NSLog(@"%@", [error description]);
return response;
}
Any suggestion would be appreciated.
First, the code looks good to me.
I would do a memory profile with instruments to make sure the app don't leaks memory. Since this code is likely the most called code of your app, it's also more likely to crash there if the app state gets corrupted. Also you should test your hardware for the same reason (http://osxdaily.com/2011/05/03/memtest-mac-ram-test/).
Also your code is easy to isolate so you can make a test app with just calls your URL or even some public URLs. If you can get this app to crash as well, you have everything to file a bug at Apple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With