Sometimes my iPhone application crashes with a weird crashlog, that reads exception code is 0x8badf00d. The stacktraces show random snapshots of app execution, but nothing suspicious. This happens very rarely and I'm not able to find out how to reproduce it. Does anybody know more about this kind of exception and exception code?
Here is an excerpt from my crashlogs:
Exception Type: 00000020
Exception Codes: 0x8badf00d
Highlighted Thread: 0
Application Specific Information:
Failed to deactivate
Thread 0:
...
< nothing suspicious here >
...
Unknown thread crashed with unknown flavor: 5, state_count: 1
0x8badf00d is the error code that the watchdog raises when an application takes too long to launch or terminate. See Apple's Crash Reporting for iPhone OS Applications document
If you get Exception Type: 00000020 and Exception Codes: 0x8badf00d then it is watchdog timeout crash reports. The exception code 0x8badf00d is called "ate bad food".
The most common reason for this crash is synchronous activity on main thread. The fix is to switch to asynchronous activity on main thread.
Refer this Apple document for more detail.
It is HexSpeak, see here: http://en.wikipedia.org/wiki/Hexspeak
It's some programmer's idea of a joke. You have to pick a number for your code, but the number doesn't necessarily mean anything in itself. 8badf00d is just another way to write the number 2,343,432,205, and was chosen because it looks 'funny' when represented in hex for an exception log.
0x8badf00d exception is raised by apple provided watchdog. The most common cause for watchdog timeout crashes in a network application is synchronous networking on the main thread. There are four contributing factors here:
synchronous networking — This is where you make a network request and block waiting for the response.main thread — Synchronous networking is less than ideal in general, but it causes specific problems if you do it on the main thread. Remember that the main thread is responsible for running the user interface. If you block the main thread for any significant amount of time, the user interface becomes unacceptably unresponsive.long timeouts — If the network just goes away (for example, the user is on a train which goes into a tunnel), any pending network request won't fail until some timeout has expired. Most network timeouts are measured in minutes, meaning that a blocked synchronous network request on the main thread can keep the user interface unresponsive for minutes at a time.Trying to avoid this problem by reducing the network timeout is not a good idea. In some situations it can take many seconds for a network request to succeed, and if you always time out early then you'll never make any progress at all.watchdog — In order to keep the user interface responsive, iOS includes a watchdog mechanism. If your application fails to respond to certain user interface events (launch, suspend, resume, terminate) in time, the watchdog will kill your application and generate a watchdog timeout crash report. The amount of time the watchdog gives you is not formally documented, but it's always less than a network timeout.
There are two common solutions:
asynchronous networking — The best solution to this problem is to run your networking code asynchronously. Asynchronous networking code has a number of advantages, not least of which is that it lets you access the network safely without having to worry about threads.synchronous networking on a secondary thread — If it's prohibitively difficult to run your networking code asynchronously (perhaps you're working with a large portable code base that assumes synchronous networking), you can avoid the watchdog by running your synchronous code on a secondary thread.
Refer apple docs for more information.
It's a failure code added by a dev with a good sense of humor. Because hexadecimal uses letters as well as numbers, it's possible to come up with hex numbers that look approximately like english words, such as "0xdeadbeef", etc. I'm sure that the exception has a specific meaning, but if there's no major symptoms associated with it, you can probably ignore it without too much concern.
from wikipedia 0xBAADF00D ("bad food") is used by Microsoft's LocalAlloc(LMEM_FIXED) to indicate uninitialised allocated heap memory when the debug heap is used.[7]
Related
I have a background thread that is doing a bunch of work - loading the application. The main thread is displaying progress on a UIProgressView.
The background thread is being spawned with performSelectorInBackground (though, I'm not wed to this method if a different approach makes this problem easier to solve)
[self performSelectorInBackground:#selector(loadAppInBackground) withObject:self];
On a couple occasions a bug has caused the background thread to crash (different bugs as the app evolves) which results in the progress bar stopping, but the user getting no clear indication that anything is wrong.
I'd like to detect this situation and fail more gracefully than simply hanging until the user gives up on waiting.
Because the duration of the load process can vary greatly, simply timing out isn't an ideal option.
What's the best way for the foreground thread to detect that the background thread has failed? Since the foreground thread is busy dealing with the UI, would it require a second background thread to monitor the first? That seems ugly.
Is there some thread-to-thread communication mechanism that could be used to "ping" the background process? Better yet, a low level system mechanism of checking the status of other threads?
The debugger knows about all the threads that are running... and seems to know their status. I'm wondering if there's a call available to my app to do the same.
If the background task runs in some sort of regular cycle (eg, there's a big loop where much of the work gets done), it can set a flag every so often to indicate that it's still alive.
One way to do this is to have background thread store [NSDate timeIntervalSinceReferenceDate] somewhere, and, in your main thread, occasionally (perhaps on a timer) compare that to the current time. If the difference is greater than some reasonable limit you can guess that the background thread has died.
Another way is to have the background thread simply set a Boolean, and have the main thread interrogate that and clear it on some regular basis. If the Boolean doesn't get set again between main thread interrogations you can infer that it has died.
The first technique has the advantage that you can "tune" the "reasonable limit" to tolerate code (in either thread) that is somewhat irregular in it's timing. The second approach generally requires timings that are more predictable.
Of course with either approach you want to somehow avoid "blowing the whistle" if the background thread has just finished up and you simply haven't recognized that yet.
A common technique is to have an extra thread to check for life signs of the thread in question - a so called heartbeat thread. The heartbeat thread polls the thread by checking if it responds in a timely manner, if not, deems the thread dead and terminates it.
A simple heartbeat thread implementation would be to check a counter that is incremented regularly by the other thread, if the counter is not incremented within a certain time it is regarded as dead and then an appropriate action could be taken like restarting thread or killing app. Another more common way is if the hb thread sends messages to the thread and checks for a response with a timeout.
It seems like there is no mechanism in objective c to check the status of a background thread directly. Any of the answers provided are decent options... either timing out, or having the thread create some sort of evidence of its continued existence.
I was hoping for something a little more simple, reliable, and real-time.
I'm going to experiment with catching an exception in the thread and perhaps producing a notification like "BackgroundThreadException" that the foreground thread could listen for and react to.
We want to do additional processing (i.e. log the current state) once PLCrashReporter has detected an error (either an exception, signal, etc.) but before the app terminates. Does anyone know if this is possible using PLCrashReporter?
To expand on Andreas' answer --
I've implemented development support in trunk for -[PLCrashReporter setCrashCallbacks:], which permits the execution of a function post-crash, prior to the program exiting.
This wasn't originally included due to the difficulty of implementing async-safe code that can be executed in the context of a crashed process -- it's difficult enough to do that I didn't think anyone would want to do it.
To quote the documentation I wrote for the feature in PLCrashReporter trunk (I don't have a rendered copy posted yet, since the feature has not yet been released):
Async-Safe Programming Guide
Plausible CrashReporter provides support for executing an application specified function in the context of the crash reporter's signal handler, after the crash report has been written to disk. This was a regularly requested feature, and provides the ability to implement application finalization in the event of a crash. However, writing code intended for execution inside of a signal handler is exceptionally difficult, and is not recommended.
Program Flow and Signal Handlers
When the signal handler is called the normal flow of the program is interrupted, and your program is an unknown
state. Locks may be held, the heap may be corrupt (or in the process of being updated), and your signal
handler may invoke a function that was being executed at the time of the signal. This may result in deadlocks,
data corruption, and program termination.
Async-Safe Functions
A subset of functions are defined to be async-safe by the OS, and are safely callable from within a signal handler. If
you do implement a custom post-crash handler, it must be async-safe. A table of POSIX-defined async-safe functions
and additional information is available from the CERT programming guide - SIG30-C.
Most notably, the Objective-C runtime itself is not async-safe, and Objective-C may not be used within a signal
handler.
No, this is not possible. You would have to do your own logging and store that on the filesystem. On the next startup, you could send it alongside the crash report to your server. E.g. using QuincyKit which uses PLCrashReporter and then your own server or HockeyApp.net.
Note: I am the developer of QuincyKit and co-developer of HockeyApp.
In our iPhone application we have several tabs and selecting each tab triggers network connection. In the past we were just detaching new thread for each connection. And after several very quick tab switches application was becoming unresponsive.
Now we decided to use operation queue which supposed should control number of threads and should not allow the application to become unresponsive. But now the app becomes unresponsive even with fewer quick switches (although now it recovers from unresponsiveness quicker).
I ran the app on device from xcode and paused it after several quick switches to see the number of threads. And what I have found is that there are several threads with the following stack:
0 __workq_kernreturn
2 _init_cpu_capabilities
Any idea what are these threads and how to get rid of them?
One of the big benefits of using NSOperationQueue is that you can forget about threads and let the system worry about that for you. It sounds like the root of your problem is that you've got several operations running simultaneously that are no longer needed. Rather than worrying about the specific threads, consider getting those operations to terminate so that they're no longer using up computing resources.
For what it's worth, my guess is that those threads are being managed by Grand Central Dispatch. GCD will create worker threads to process blocks (and operations), and it'll be as efficient as it can about that.
the important part of your problem does not likely lie in the internal/private implementation of worker threads. a good implementation will likely employ a thread pool because creating one thread per operation would cost a lot. operations can reuse and hold on to idle threads.
the important part (likely) lies in your use of the public apis of the implementation you have chosen.
one obvious implementation to support in this case is operation cancellation: -[NSOperation cancel]. when somebody navigates away from a view which has a pending/unfinished request, simply cancel it (unless you'll need the data for caching).
many implementations may also benefit by making requests less often. for example: if your server results only update about once per hour, then it doesn't make sense to request it 'about every minute'.
last point: a connection can use a worker thread itself - check the apis you are using to reduce this if it's a problem.
In my application I am executing 10 asynchronous NSURLConnections within an NSOperationQueue as NSInvocationOperations. In order to prevent each operation from returning before the connection has had a chance to finish I call CFRunLoopRun() as seen here:
- (void)connectInBackground:(NSURLRequest*)URLRequest {
TTURLConnection* connection = [[TTURLConnection alloc] initWithRequest:URLRequest delegate:self];
// Prevent the thread from exiting while the asynchronous connection completes the work. Delegate methods will
// continue the run loop when the connection is finished.
CFRunLoopRun();
[connection release];
}
Once the connection finishes, the final connection delegate selector calls CFRunLoopStop(CFRunLoopGetCurrent()) to resume the execution in connectInBackground(), allowing it to return normally:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
...
// Resume execution where CFRunLoopRun() was called.
CFRunLoopStop(CFRunLoopGetCurrent());
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
...
// Resume execution where CFRunLoopRun() was called.
CFRunLoopStop(CFRunLoopGetCurrent());
}
This works well and it is thread safe because I bundled each connection's response and data as instance variables in the TTURLConnection subclass.
NSOperationQueue claims that leaving its maximum number of concurrent operations as NSOperationQueueDefaultMaxConcurrentOperationCount allows it to adjust the number of operations dynamically, however, in this case it always decides that 1 is enough. Since that is not what I want, I have changed the maximum number to 10 and it seriously hauls now.
The problem with this is that these threads (with the help of SpringBoard and DTMobileIS) consume all of the available CPU time and cause the main thread to become latent. In other words, once the CPU is 100% utilized, the main thread is not processing UI events as fast as it needs to in order to maintain a smooth UI. Specifically, table view scrolling becomes jittery.
Process Name % CPU
SpringBoard 45.1
MyApp 33.8
DTMobileIS 12.2
...
While the user interacts with the screen or the table is scrolling the main thread's priority becomes 1.0 (the highest possible) and its run loop mode becomes UIEventTrackingMode. Each of the operation's threads are 0.5 priority by default and the asynchronous connections run in the NSDefaultRunLoopMode. Due to my limited understanding of how threads and their run loops interact based on priorities and modes, I am stumped.
Is there a way to safely consume all available CPU time in my app's background threads while still guaranteeing that its main thread is given as much of the CPU as it needs? Perhaps by forcing the main thread to run as often as it needs to? (I thought thread priorities would have taken care of that.)
UPDATE 12/23:
I have finally started getting a handle on the CPU Sampler and found most of the reasons why the UI was becoming jittery. First of all, my software was calling a library which had mutual exclusion semaphores. These locks were blocking the main thread for short periods of time causing the scroll to skip slightly.
In addition, I found some expensive NSFileManager calls and md5 hashing functions which were taking too much time to run. Allocating big objects too frequently caused some other performance hits in the main thread.
I have begun to resolve these issues and the performance is already much better than before. I have 5 simultaneous connections and the scrolling is smooth, but I still have more work to do. I am planning to write a guide on how to use the CPU Sampler to detect and fix issues that affect the main thread's performance. Thanks for the comments so far, they were helpful!
UPDATE 1/14/2010:
After achieving acceptable performance I began to realize that the CFNetwork framework was leaking memory occasionally. Exceptions were randomly (however, rarely) being raised inside CFNetwork too! I tried everything I could to avoid those problems but nothing worked. I am quite sure that the issues are due to defects within NSURLConnection itself. I wrote test programs which did nothing except exercise NSURLConnection and they were still crashing and leaking.
Ultimately I replaced NSURLConnection with ASIHTTPRequest and the crashing stopped entirely. CFNetwork almost never leaks, however, there is still one very rare leak which occurs when resolving a DNS name. I am quite satisfied now. Hopefully this information saves you some time!
In practice you simply cannot have more than two or three background network threads and have the UI stay fully responsive.
Optimize for user responsiveness, it's the only thing a user really notices. Or (and I really hate to say this) add a "Turbo" button to your app that puts up a non-interactive modal dialog and increases concurrent operations to 10 while it is up.
It sounds as though NSOperationQueueDefaultMaxConcurrentOperationCount is set to 1 for a reason! I think you're just overloading your poor phone. You may be able to mess around with threading priorities -- I think the Mach core is available and part of the officially blessed API -- but to me it sounds like the wrong approach.
One of the advantages of using "system" constants is that Apple can tune the app for you. How are you going to tune this to run on an original iPhone? Is 10 high enough for next years quad-core iPhone?
James, although I haven't experienced your problem, what I've had success with is using the synchronous connection for downloading within an NSOperation subclass.
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
I use this approach for grabbing image assets from network locations and updating the target UIImageViews. The download occurs in NSOperationQueue and the method that updates the image-view is performed on the main thread.
we have an asp.net application, that makes heavy use of REST/json services through httpwebrequest and heavy use of the web cache. seemingly sporadically, the worker process simply stops responding. the browser sits expecting a response and never gets one. only an app pool restart seems to remedy the problem. there are no unhandled exceptions or any other anomalies that we have noticed. cpu and memory loads are low (<10% cpu util, >80% free memory)
the only possible hint that we have had is that we saw 'deadlock detected' messages in the event log at one point, but not consistently. additionally, we've eliminated what we think to be the only possible cause of such contention (executing multiple concurrent httpwebrequests via begin/end request).
any ideas?
win 03 server/data center edition (on amazon ec2)
asp.net 3.5
When you have a non-responsive application with low cpu used, it's most likely a concurrency issue. You either have deadlocks which cause all your threads to stall, or your asynchronous threads take forever to finish and the ThreadPool ends up starving. Since you're running ASP.Net, you should check how the ThreadPool is doing. You can watch the performance counters or, better, attach to your application with windbg (you can get it from Debugging Tools for Windows http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx).
Launch windbg, attach to the asp.net process and then, in the command prompt:
.loadby mscorwks sos
!ThreadPool
Even better, download the sosex extension (http://www.stevestechspot.com/CommentView,guid,9fdcf4a4-6e09-4807-bc31-ac1adf836f6c.aspx) and check for deadlocks with
!dlk
check what are the threads blocking, switch to one of the threads (using the UI or the command line) and type
!CLRStack
to have a stack trace showing you which method is blocking your application.