Is there a way to send low memory crash reports with QuincyKit?
I looked through the code, and QuincyKit sends the crash reports found in:
/var/mobile/Application//Library/Caches/crashes
However when the app crashes due to a memory warning a file doesn't get created in that directory. I can view the low memory reports in Organizer (type Unknown), but where is the file located?
Can QuincyKit be modified quickly to send the memory reports?
Unfortunately this is not possible.
Out of memory crashes are actually kills by the watchdog process. Whenever you kill a process, there is no crash happening. The crash reports for those that you see in Organizer, are arbitrary reports written by the watchdog process that did the kill. So the only system that can provide information about these, is iOS itself.
It is not possible to retrieve the memory reports.
However, it would be possible to notice:
that a memory warning had been received and record the memory usage at that time - and
that X seconds later the application was no longer running (by maintaining a simple watchdog thread).
You could then deduce on the next run that the application had probably been killed due to an out of memory condition, and you would have some information about the memory usage at that time. Indeed, you could extend your memory warning handler to report the size of any caches you were running (and also to clean them up at the same time, thereby reducing the likelihood of a crash!).
Related
Recently I had an issue in my iOS app that caused the app to freeze. The UI was unresponsive and the user had to kill and restart the app to make it work again.
In Google's Play Console I see such issues as ANRs ('Application not responding' errors).
But in Xcode I don't get any reports unfortunately. Crashlytics also didn't show any reports.
Is it possible to somehow get some kind of report with a stacktrace similar to the ANRs in Google's Play Console?
Please note:
I know what caused the app to freeze in this specific issue and also how to debug and fix it. What I
want is an error report in case the issue wasn't found during QA but it is
occurring in a user session.
The freezing version was not published to App Store, only to
TestFlight.
The reason for unresponsive UIs could be due to a number of reasons:
One reason could be because of high load (running out of RAM, Swap Space). For detecting these scenarios (without crashing behavior) you need Application Performance Monitoring, for example with Firebase. The advantage with Firebase is you don't have to prompt for consent, so you get more data to detect hangs. The Xcode Organizer can provide Hang Rate metrics though if you have enough users who have consented to share their data (new in Xcode 11).
Another reason could be due to logical errors in code. For example, a user triggers an unexpected app flow that was missed during manual testing. In these instances, it can be harder to narrow down but could be trackable with manual user testing beforehand e.g TestFlight. You can use In-App Feedback tools (users send you emails) to gather context about the issue or Instabug for screenshots and advanced feedback.
The other reason could be because of deadlocks. If you use DispatchGroup for instance or DispatchSemaphores to queue network requests and the requests time out then that could also lead to suspended UI frames. I would look carefully at where you leave the dispatch group as well - all possible branches should have a dispatch_group_leave statement to avoid hanging on dispatch_group_wait.
You can use the Thread State Trace Instrument to see whether system calls are blocking your main thread to debug this issue. The classic iOS dev advice is to only perform UI updates on the main thread and move all other logic to a background thread. This may not solve the root cause but does prevent hangs. The same logic applies for Core Data fetches, inserts, deletes, and updates. Move Core Data operations to background threads in network request callbacks as well.
If you get crash reports, it's simple to diagnose an OOM error in a Crashlytics crash report for example (comes up in Insights). Heap corruption can also be inferred from crash reports, and while the metadata may not be the same for the same behavior, it could point you to a screen or action when you try and reproduce the bug.
Watchdog Unresponsive App crashes can be intercepted to come up in crash reports if the user doesn't kill the app beforehand, but you mentioned the user killed the app so this may not be available.
There is no direct equivalent ANR error reporting for iOS apps, given that Hang Rates are only aggregated if enough sessions have been detected. You could do screen recording of app sessions (ServiceNow), but I don't advise it because it has privacy implications.
Crashlytics is unable to send abnormal terminations fired by the watchdog. I've researched this for Jetsam terminations. You will see them in the console logs. see this link for the watchdog crash iOS generates: Watchdog Unresponsive App. If there's a way to monitor the main thread for queued operations executing for too long, you could fire a fatal error ie fire a fatal before the watchdog terminates the app.
Do some research on MetricKit. It's new to iOS 13. There's a class called MXHangDiagnostic. You can use it in your app to monitor for hangs and report on them as you see fit.
I am working on a iOS Application for >=iOS8 Devices. My app is memory intensive which becomes a problem since the app can crash. I have CrashLoggers in place that report crashes on the app during the next start. However there are certain scenarios when the app may consume higher than usual memory and the OS may terminate it. Is there any delegate that I could use to detect an OS forced app termination?
I tried [AppDelegate applicationWillTerminate:] and [AppDelegate applicationDidReceiveMemoryWarning:] but they are going to give me false positives for the most part. The problem is that this is not a exception, but a system signal raised by OS to kill the app that I am trying to detect within the scope of the event.
I am a new programmer. Let me know if I am understanding things incorrectly or I am making impractical assumptions.
I have read the following links:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/applicationWillTerminate:
Is there any method in appDelegate which is called when application crashes?
I understand that preventing the problem is better than cure. But here I am trying to detect if there's going to be a problem. It's not like the app always crashes. There may be some edge case scenarios or users on very old devices like iPhone 4s/iPad Air 1 for which the app can run (possibly) into problems. So, I need a logging mechanism around this.
The runtime of the app is ~120MB worst case which is high but well under the range of too high. While the app has a lot of features, Image processing in the app is difficult to perform while maintaining the quality and also to profile in terms of memory(spikes depend on size, quality of image, lighting, etc.). So my app is well within the boundary line, and I am asking for way to detect if the app crosses this boundary when used by the user.
I totally agree with optimization(or fixing the crash) suggestion that you gave, and I would try my best to optimize(or de-bug) the app.
When app crashes or is killed by the system, there is no signal that you can catch meaningfully.
What makes you think applicationDidReceiveMemoryWarning: is giving you false warnings?
Receiving a memory warning and then not being killed is not a false positive. That just means your app didn't increase memory allocations enough to cross the threshold.
When you receive a memory warning, log if you want, but also decrease memory usage.
How do you know that the maximum runtime allocation footprint is 120MB? Depending on device, you'll have anywhere from around 125MB (iPad 1) to well over 1GB of memory available on modern devices (more on iPad Pro).
You should be getting your applicationDidReceiveMemoryWarning: called when the system is under memory pressure. This can be simulated by selecting the Simulate Memory Warning menu item in the Hardware menu.
If you actually go over your memory limit on device, you'll get jetsamed (SIGKILLed). You can't detect that.
If you want to simulate the jetsam, just send your process a SIGKILL (kill -9 <pid>)
How can I solve this problem, I don't know that did it affect to my problem in this link My previous problem about Core data ?
This message will occur when I cmd+Q of the application.
Message from debugger: Terminated due to signal 15
and if who know the solution of my previous problem please tell me.
Message from debugger: Terminated due to signal 15 occurs whenever the user manually terminates the application (whether simulated in iOS simulator or on a provisioned iOS device) through CMD-Q (Quit) or STOP, which is toggled after you click on RUN.
In OS terms, signal 15 is a Linux enumeration for the signal, SIGTERM, which means signal terminate.
Message from debugger: Terminated due to signal 15 usually means that you quit the simulator while running the program.
I have same issue when i take screen short from simulator then terminated. This is xcode bug.
Just update your xcode version.
This only means that the system sent your application the kill signal. The system may do that for any number of reasons. It does not necessarily mean the application was killed due to memory pressure. In fact, this is very unlikely in the case that you describe. Most of the reasons the system might send a kill signal won't happen when the app is being debugged.
When the system kills an application it will track the reason and log it. If you are using a third party crash reporting service this will not capture the reason, and in fact can prevent a lot of critical information from being logged by the system.
Look for logs on the device. Watch the console log on the device when the issues reproduces - usually you will be able to see why it was killed. If it was memory pressure there would be a JetsamEvent log as well.
It is much more likely that your application is doing something "in the background" that it does not have a background mode or entitlement for. For example, it may be doing something past the background task assertion time limit, etc.
As far as your CPU and memory use, do not trust the gauges in Xcode. These are just an estimate and are often way off, and they do not capture the information you actually need (like dirty VM usage). Instead use Instruments.
https://www.reddit.com/r/iOSProgramming/comments/822id9/ideas_for_debugging_a_memory_leak_terminated_due/
I can't determine the cause of a crash.
While running the debug build of an app on an iPad 3.1 from Xcode, the app terminates but the debugger doesn't tell me anything. I have an all-exceptions breakpoint and that has certainly worked in the past to catch errors.
Not that I know how to use a crash dump, but when this happens the "Device Log" in the organizer devices pane shows an entry from process "Unknown" of type "Unknown".
I am also having memory warning problems, but in this case I'm not getting the memory warning method invoked (I have a log message and a breakpoint). Could this be a memory warning that doesn't invoke the method ever? [The memory warnings are a puzzle since Instruments isn't showing me any leaks and my own image objects aren't (obviously) being kept in memory -- but that's another problem].
Any idea what is happening to me and how I could get the debugger to trap the condition?
This sounds like your app is getting killed by the system because you allocate too much memory. Depending on how much memory you are allocating, it could very well happen that you never see the memory warning methods being called.
Check your app with instruments running and also check the crash report again, it should give you some more details. E.g. a list of processes with rpages, recent_max and (state) columns, with Largest process: shown above. I bet your process is named and also shows the state (suspended), which means: iOS killed it because you allocated too much memory.
My iPad app always gives memory warning level 1 or 2, but NEVER crashes. It just display log for warning level 1 or 2, but I CAN continue operate on my app without any problem.
Also I have used activity instrument to monitor the memory usage of my app. It costs at most (peak) 40 MB in the life time.
Can someone tell me why? why it still gives warning when it only used up to 40 mb and never crashes?
Thanks
My iPad app always gives memory warning level 1 or 2, but NEVER crashes. It just display log for warning level 1 or 2, but I CAN continue operate on my app without any problem.
That's exactly how the system is supposed to work. The OS sends memory warnings to every process, and everybody frees some unneeded memory. The OS itself can also kill apps that are currently in the background. If enough memory can be freed, nothing needs to be killed. What good would the warnings be when your app would get killed every time anyway?