Using PLCrashReporter, can you receive events before the crash? - iphone

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.

Related

Using a vkFence with an std::condition_variable

A VkFence can be waited upon or queried about its state. Is it possible to have a callback invoked by the Vulkan implementation when the fence is ready instead?
This would allow it to be used with objects such as a std::condition_variable. When the fence would be ready, the condition_variable would get notified.
Such an approach would also allow integration with libraries like Boost.Fiber, which would completely remove the need for the thread to sleep, but rather it could do useful work while waiting upon the fence.
If this is not possible in base Vulkan, is there an extension that allows it?
Vulkan doesn't work that way. Vulkan devices and queues execute independently of the CPU. Indeed, with one or two exceptions, Vulkan implementations only ever use CPU resources within the scope of a particular function call and only on the thread on which this call was made. Even debug callbacks are made within the scope of the function that caused the error.
There is no mechanism for Vulkan implementations to use CPU resources without the explicit consent of the user of the API (again, minus one or two exceptions). So no callbacks that act outside of an API call.
Vulkan does have a way to extract a native synchronization object from a VkFence, but it is surprisingly not useful in Windows. While you can get a HANDLE, it cannot be used by the Win32 API for waiting on it. This is mainly for interop with other APIs (like converting it to a D3D12 sync object), not for waiting on it yourself. But the file descriptor extraction operation can get a fully functional sync object... if the implementation lets you.

How to detect Force Close on Mac OS X app

I have a Mac OS X app and I want to detect or catch the event when the user Force Close my app.
At first I thought applicationWillTerminate will do the work but it didn't:
func applicationWillTerminate(_ aNotification: Notification) {
print("applicationWillTerminate called")
}
Do you have any idea how can I do that?
Major credit goes to #caseynolan for putting work in here to come up with an answer. Unfortunately, there are, in fact, some major issues with the suggested approach.
First, signal handlers are per-process. There are other, legitimate uses of signals, and installing handlers will negatively impact their behavior without very careful work.
Second, signals interrupt a thread, and that thread can be doing anything, including holding locks. Examples of things that hold locks - malloc/free, the Objective-C runtime.
This is an part of a class of problems known as "async safety". If you check out "man sigaction" (note, sigaction is a much improved API over signal) you see that there are actually a very small number of functions that are safe to call from a signal handler. Calling unsafe functions, like NSLog, will sometimes work. But, will also sometimes deadlock, depending on what the thread was doing at the time.
Now, I will admit that my experience with signals does not include use of SIGTERM. However, since it can be delivered at any time, it still will be subject to async safety issues, even thought it is not a crash.
In short: it is almost certainly unsafe to run your code in a signal handler, and it will deadlock sometimes. And, those deadlocks will occur during unpredictable points of its execution.
Third, there are fatal events that aren't mapped to signals, on top of SIGKILL. This may not matter to do, depending on how strong a guarantee you need about detecting your process termination.
What I'd do Instead:
I think you're only safe option is to use a sentinel process. The idea is you start up a child process, and in that child, observe the parent. If/when that process disappears, you can then execute your code.
This is a safe, deadlock-risk free way to monitor for arbitrary process exits. However, it could be challenging to move your operations out-of-process. Unfortunately, I believe that's a necessary aspect of this, if you want it to be reliable.
Good luck!
Disclaimer: I'm not an expert, and researching for this post has stretched the limits of my rusty C/Objective-C knowledge. I don't know how the following code is viewed by Apple for submissions to the App Store, so YMMV.
The following has been shamelessly ripped from Wikipedia and reworked:
#import <Foundation/Foundation.h>
/**
This will handle signals for us, specifically SIGTERM.
*/
void handleSignal(int sig) {
if (sig == SIGTERM) {
// Caught a SIGTERM
}
/*
SIGTERM is a clear directive to quit, so we exit
and return the signal number for us to inspect if we desire.
We can actually omit the exit(), and everything
will still build normally.
If you Force Quit the application, it will still eventually
exit, suggesting a follow-up SIGKILL is sent.
*/
exit(sig);
}
/**
This will let us set a handler for a specific signal (SIGTERM in this case)
*/
void setHandler() {
if (signal(SIGTERM, handleSignal) == SIG_ERR) {
NSLog(#"Failed to set a signal handler.");
} else {
NSLog(#"Successfully set a signal handler.");
}
}
Call only asynchronous-safe functions within signal handlers. See here.
You could place the above in a C/Objective-C file and use it in Swift via a Bridging Header. Call setHandler() somewhere in the beginning of your application's lifecycle, e.g. in applicationDidFinishLaunching, and you should now have a chance to do some work before your app is Force Quit. I don't know how much time you get here, so I'd keep the workload as light as possible (avoid starting mission-critical stuff here, I guess?).
Here's some background info:
In a typical Quit
The Quit procedure is actually a part of Apple Events.
If the application is NSDocument-based, the behavior depends on the saving parameter, which has one of these three values:
NSSaveOptionsNo: The application quits without sending a close message to any document.
NSSaveOptionsYes: Each unmodified document is sent a close message; each modified document is sent the following message:
saveDocumentWithDelegate:didSaveSelector:contextInfo:
NSSaveOptionsAsk: (This is the default value if no saving parameter is supplied in the event.) If there are modified documents
open, the NSDocumentController sends itself this message:
reviewUnsavedDocumentsWithAlertTitle:cancellable:delegate:didReviewAllSelector:contextInfo:
If the application is not NSDocument-based, the application delegate is sent this message (if it is implemented):
applicationShouldTerminate:
You can modify the default behavior by implementing this method.
Source: How Cocoa Applications Handle Apple Events
During Force Quit
The application is sent a SIGTERM which can be caught and dealt with by your application. Ideally, the application would clean up and exit as gracefully as possible, but this isn't required, and the signal can even be ignored.
An impatient user (and I strongly suspect that Force Quit does this eventually) may send a SIGKILL, which cannot be ignored and totally goes over anything you as the developer can stop.
Extra Information and Resources:
What does Force Quit do in OS X?
What signals does OS X send for the Quit and Force Quit commands?
How Cocoa Applications Handle Apple Events
SIGTERM vs. SIGKILL - major.io
C Signal Handling - Wikipedia

Why a form is needed for a SetWinEventHook callback?

Currently, I'm using the powerful SetWinEventHook() function to catch some user-interface's actions like minimizing and maximizing from other window runned by programs on the computer.
So I inspired myself by using the code provided by BrendanMcK on this post and it does work (I mean: the callback function is called when an event occurs) until the line
MessageBox.Show("Something")
is present. But I don't want to use any form or window for this program..
After some research, I figured out this kind of hook needs a message loop to allow the redirection of messages from other window handles. Apparently, calling the thread using Application.Run() should do the trick, but I would prefer something cleaner, in the C# object itself.
So my question is: is it possible to create a message loop inside an object's method?
http://bytes.com/topic/c-sharp/answers/557342-thread-message-loop-c
No, the function doesn't require a window handle so no "form" is needed. But the MSDN docs for the function is quite explicit:
The client thread that calls SetWinEventHook must have a message loop in order to receive events.
A message loop is universal in any program that want to receive notifications that are generated externally by other processes or threads. It is the common solution to the producer-consumer problem. Clearly any GUI app has a need for such a solution, Windows messages are generated by the operating system. It isn't different for SetWinEventHook(), the accessibility events originate in other programs. There is no clean mechanism to "interrupt" a thread and make it run other code, the re-entrancy problems that causes are extremely difficult to deal with. The thread has to co-operate, it must be idle and ready to receive a notification to safely process it. A message loop solves that problem.
Pumping a message loop (calling Application.Run) in a method is certainly possible. But do keep in mind that the method won't return until you explicitly stop the loop with Application.ExitThread. There is therefore usually only one good place for that call, the Main() method of your program.
Starting your project with a Winforms or WPF project template is a very good way to get this right. You have no need to actually create a window, call Application.Run() without an argument, after pinvoking SetWinEventHook.

How is multitasking implemented at the elementary level?

How is the multitasking implemented at the basic level ? To clarify my question, lets say we are given a C runtime to make an application which implements multitasking, which can run only one task at a time on a single core processor, say, by calling main() function of this "mutlitasking" application.
How do standard OS kernels implement this ? How does this change with multicore processors
OS sets an interrupt timer, and lets the program run. Once the timer expires, control flow jumps to code of the OS for context switch.
On the context switch OS saves registers and supporting data of the current process and replaces it in CPU with data of the next process in queue. Then it sets another interrupt timer and let the next program run from where it was interrupted.
Also a system call from the current process gives control to the OS to decide if it is time for a context switch (eq. process is waiting for an IO operation)
The mechanics is transparent for programs.
Run. Switch. Repeat. :)
I've not done much work with multi-core processors, so I will refrain from attempting to answer that part of the query. However, with uniprocessors, two strategies come to mind when it comes to multi-tasking.
If I remember correctly, the x86 supports hardware task switching. (I've had minimal experience with this type of multi-tasking.) From what I recall, when the processor detects the conditions for a task switch, it automatically saves all the registers of the outgoing task into its Task State Segment (x86), and loads all the registers from the incoming task's Task State Segment. There are various caveats and limitations with this approach such as the 'busy bit' being set and only being able to switched back to a 'busy task' under special conditions. Personally, I do not find this method to be particularly useful to me.
The more common solution that I have seen is task switching by software. This, can be broken down into cooperative task switching and pre-emptive task switching. If you are coding up a cooperative task switching strategy, a task switch only occurs when the task voluntarily gives up the processor. In this strategy, you only need to save and load the non-volatile registers. If a pre-emptive strategy is chosen, then a task switch can occur either voluntarily, or non-voluntarily. In this case, all the registers must be saved and loaded. When coding either scenario, you have to pay extra care that you do not corrupt your register contents and that you set up your stack correctly so that when you return from task-switching code you are at the right place on the stack of the incoming task.
Hope this helps.

What does 8badf00d mean?

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]