My name is Mike Ash, and I’d like to talk to you about our acquisition of VoodooPad and the way I’ve put it to use for many different things over the years. I’m a software engineer here at Plausible Labs. I wear a lot of other hats as well. Plausible Labs is a cooperative, which means that all of us here at Plausible share in the ownership and decision-making of the company. I helped get the ball rolling on VoodooPad, although the decision was made collectively as befits our corporate structure. I’m also going to be the principal engineer working on VoodooPad for the moment, and I’m happy to get my hands dirty.
Some of you may know me from NSBlog, home of the Friday Q&A series of articles about Mac and iOS programming. As it happens, I do all of my blog writing in VoodooPad these days.
I first discovered VoodooPad way back when it was fresh and new, around the original release in 2003. I was enchanted at the prospect of being able to organize my personal data in a personal wiki. Before that, I had a mass of text files strewn about my computer. A lot of them lived on the desktop. More of them lived in a folder on the desktop, where I occasionally “organized” files that I’d kept around for a while. Still more lived in random, unfathomable places.
I started a VoodooPad document with that old version and called it “Random Notes”. I still have that same document today, now upgraded to a VoodooPad 5 document and filled with lots of data from over the years. I started out by filling it up with those assorted text files and finally getting rid of my desktop clutter. (It came back within hours, but now it’s at least limited to images and zip files and other non-textual information.) Then I started adding more. Now this document is filled with everything from insurance policy numbers to assorted programming tricks to notes on places to fly gliders in China. Some of this stuff is tremendously old and completely useless to me now, but the personal wiki concept lets me keep everything around without any clutter, and I never have to worry about deleting something I’ll later need.
With the release of VoodooPad 5, it gained support for the Markdown syntax. By a wonderful coincidence, my blog uses the Markdown syntax. I saw this as the perfect opportunity to move away from a painful system of text files and scripts and streamline the process of writing my articles. I wrote a small script that sends an article to my blog server, and now I do all of my writing from within my master VoodooPad document. It’s not built as a blogging platform, but the power and flexibility of the system lets me mold it to my needs.
VoodooPad has been indispensable to me for years. Looking back, I believe I’ve used it for a longer time than any other piece of third-party software I’ve used since I first laid hands on a Commodore 64 back in the mid-80s. I’m excited to move up from a user of the app to a developer, and hope that we can give many more years of solid updates for a powerful and flexible app.
The first Plausible release of VoodooPad is version 5.1.3. It contains a few bug fixes that Gus, head of Flying Meat made since 5.1.2, and it also changes names and URLs around as appropriate. We’re now hard at work on a 5.2 release following the road map from Gus. I’m a firm believer in software that’s done when it’s done, so I don’t want to make any promises on a timeframe, but I certainly don’t want to keep you waiting too long!
I’m pleased to announce the first beta release of PLCrashReporter 1.2. Plausible CrashReporter provides an open source in-process crash reporting framework for use on both the iPhone and Mac OS X, and is used by most of the first-tier commercial crash reporting services for Mac OS X and iOS.
This is the first major update to PLCrashReporter’s design since the 1.0 release, and there’s a lot of significant improvements — and we’ve set the stage for some even more significant enhancements for Mac OS X and iOS in the future. The extensive work on this release was funded by Plausible Labs and HockeyApp via the PLCrashReporter Consortium.
New features in this release include:
- Experimental ARM64 support.
- Mach-based exception handling on Mac OS X and iOS (configurable).
- Client-side symbolication using the Mach-O symbol table and Objective-C meta-data (configurable).
- Enhanced stack unwinding using both DWARF and Apple’s Compact Unwind data when available (i386, and x86-64, ARM64 forthcoming).
- Support for tracking preserved non-volatile registers across frame walking. Allows for providing non-volatile register state for frames other than the first frame when using compact or DWARF-based unwinding.
- Back-end support for out-of-process execution.
- A unique incident identifier is now included in all reports.
- Reports now include the application’s start time. This can be used to determine (along with the crash report timestamp) if an application is crashing on launch.
- Build and runtime configuration support for enabling/disabling local symbolication and Mach exception-based reporting.
- Mac OS X x86-64 is now a fully supported target.
More details on a few of the big (and cool) features:
We’ve implemented baseline support for ARM64, including all the necessary assembly/architecture code changes. For this initial release — prior to the availability of actual iPhone 5S hardware — we’re providing a separate binary release that includes ARM64 support. This is intended to allow projects that depend on PLCrashReporter to experiment with integrating arm64 into their builds; applications should not be released with PLCrashReporter/ARM64 until the implementation has been validated against actual hardware.
Once we have ARM64 hardware in hand, we’ll validate our implementation via our test suite and fix any issues that likely exist. One of the most exciting changes that we’ll be investigating after the release of the iPhone 5S is support for frame unwinding using the now-available ARM64 compact unwind and DWARF eh_frame data; this will provide the best possible stack traces on iOS, and has not been available for arm32 targets.
Mach Exception Handling
This release supports the use of optional Mach exception handling, rather than a standard POSIX signal handler. The use of Mach exception handling can be configured at runtime, or can easily be excluded/included from the entire build at compile-time.
Mach exceptions differ from POSIX signals in three significant ways:
- Exception information is delivered as a Mach message via a Mach IPC port, rather than by the kernel calling into a userspace trampoline.
- Exception handlers may be registered by any process that has the appropriate mach port rights for the target process.
- Exception handlers may be registered for a specific thread, a specific task (process), or for the entire host. The kernel will search for handlers in that order.
These properties can be useful for a crash reporter; they allow us to operate a reporter entirely out-of-process on platforms where this is supported (eg, Mac OS X), they allow us to create multiple tiers of crash reporting (eg, we can register a per-thread Mach exception handler that detects only crashes that occur in our own crash reporter), and they allow us to catch crashes that leave the currently executing thread in a non-viable state (such as due to a stack overflow, in which case there is no room on the target thread’s stack for the signal handler’s frame).
However, there are also some downsides, which is why Mach exceptions have been such a long time coming to PLCrashReporter, and why they remain optional:
- On iOS, the APIs required to implement Mach exception handling are not fully public — more details on the implications of this may be found in the API documentation referenced below.
- A Mach exception handler may conflict with any managed runtime that registers a BSD signal handler that can safely handle otherwise fatal signals, allowing execution to proceed. This includes products such as Xamarin for iOS.
- Interpretation of particular fault types often requires information that is architecture/kernel specific, and either partially defined or undefined.
In some circles, Mach exception handling has been described as the “holy grail” of crash reporting. I think that’s a bit of a misnomer; I’d be tempted to call them the “holy hand grenade”; they provide some advantages, but can just as easily explode in an implementor’s hand. In the process of implementing this feature, we found (and worked around) two separate kernel bugs that resulted in an in-kernel deadlock caused by in-process use of Mach exceptions. The fact is that Apple treats Mach exceptions as a partially exposed private API, and the only truly supported consumer of Mach exceptions is Apple’s own Crash Reporting implementation.
Our general recommendation is to continue to use POSIX signal handlers on iOS; for further information, refer to PLCrashReporter’s Mach Exceptions on Mac OS X and iOS documentation.
Mach exception handling may be enabled via -[PLCrashReporter initWithConfiguration:].
While DWARF debugging information is necessary for first-class symbolication, it’s not always available; for example, when running an in-development copy of your code on your phone for which you lost the dSYM by performing a rebuild. Traditionally, the crash report generated by such a case is useless, as you have no reasonable way of matching it up to even symbol names.
To help in these instances, we’ve implemented support for client-side symbolication, which will provide basic symbol information even when the dSYM is long-gone. Our implementation goes quite a bit beyond most other systems, in that in addition to using the Mach-O symbol table (which is often stripped, or in the case of iOS, all symbol names are renamed to <redacted>), Mike Ash implemented async-safe introspection of the runtime Objective-C metadata to fetch class and method names for all symbols implemented in Objective-C. As far as we know, we’re the only crash reporting implementation to do this, and we think it’s pretty neat.
Client-side symbolication may be enabled via -[PLCrashReporter initWithConfiguration:]; since release builds should always have dSYMs, we recommend only enabling client-side symbolication for non-release builds.
Enhanced Stack Unwinding
On x86-64 and i386 (and soon, ARM64!), additional unwinding data is provided in-binary, and may be used to both produce better stack traces, but also to provide the state of non-volatile registers at each stage of the stack frame. To support this, we’ve implemented fully async-safe and portable implementations of DWARF eh_frame stack unwinding, as well as support for Apple’s Compact Frame encoding. This should significantly improve stack traces on Mac OS X, and once we have our hands on the hardware and can add ARM support, ARM64.
In the future, we will also be exposing the enhanced register state for all frames, making it even easier to dig into the state of the process at the time of the crash.
Since our first release of PLCrashReporter in 2008, it has come to be relied upon by analytics companies, developer tools providers, and internal corporate crash reporting services. We believe that PLCrashReporter is unrivaled as a reliable, stable, well-tested, and carefully constructed crash reporting tool.
Almost since the beginning, HockeyApp’s developers have contributed to the development of PLCrashReporter — contributing patches, developing both open-source and commercial services around it, and ultimately, funding the development of additional open-source features.
We are very excited to announce a long-term joint partnership between our two companies. This partnership will allow us to focus development efforts on further improving and expanding the reach of PLCrashReporter, as well as developing new features, services, and improvements for HockeyApp’s server and client products. The first result of this partnership will be the release of the next generation open source PLCrashReporter. Exclusive early access for HockeyApp customers and details are coming soon!
HockeyApp and Plausible Labs share a combined vision regarding the future of PLCrashReporter. We genuinely believe that complex tools such as PLCrashReporter should be open-source, in the same way that Apple provides kernel, compiler, and library sources, as to allow for peer review and validation of the approaches we have taken in our technical implementation. Integrators — whether they be application developers or platform providers — should be certain of the robustness of the software, that there is no use of private API or poor implementation that could harm their business or their customer’s interests.
To support this vision, we are launching plcrashreporter.org, a dedicated open-source project, administered by Plausible Labs. It is our goal to ensure that PLCrashReporter remains a trustworthy, free, and open-source solution to crash reporting on iOS, Mac OS X, and — in coming months — future platforms. We will also be founding the PLCrashReporter Consortium (modeled on SQLite’s), with the goal of sharing resources to fund the ongoing open-source development of PLCrashReporter.
HockeyApp is joining the PLCrashReporter Consortium as its founding member, and we look forward to other companies that rely on PLCrashReporter joining in supporting the project’s ongoing open-source development.