My toughest bug of 2014!
The first sign of a problem was when the app crashed while I was testing a new feature I’d put in. The error in VS indicated a XAML issue, which was odd since I wasn’t working with XAML at that point. I restarted the app, and no error occurred. "Meh, whatever" was my response. The second sign of a problem was when another developer on the team told me about it a week later. My response? I shrugged it off and told him to restart. The third sign was when the testers logged a bug about it—finally, someone was making this a real issue. You may have heard that a developer and tester are better than two developers—this is a great example of why: two different perspectives on what really is an issue does help.
The app we were building was a Windows Store app for Windows 8.1, using XAML and C#. It was built with the Universal App Platform—and it was big, with over 40 screens! The XAML for our custom controls and styles ran over 2,000 lines. The bug could be anywhere, but it had four key traits:
- The error suggested a XAML issue related to a ContentPresenter: Failed to assign to property 'Windows.UI.Xaml.Controls.ContentPresenter.Content'.
- It only happened when navigating between pages.
- It wasn’t limited to any one page—it could occur on any.
- It was intermittent—make-you-scream levels of intermittent. (I’ll introduce Heather later, but she told us it happened about 1 in 40 times on average!)
So how did we fix this? Here’s the story of the dumb things I did before the smart fix.
Starting to Understand the Problem
Step one: We knew it was a XAML issue affecting every page, so what was common across all of them? First, we had our styles.xaml, where we defined common colors and styles. Second, there was a custom control called PageLayout—essentially a wrapper for shared layout and functionality (similar to the Frame control). Since the error mentioned a ContentPresenter, and PageLayout had four of them, we suspected it was the culprit. I reviewed the XAML, as did another dev—no obvious issues.
But here’s the key clue: When we tweaked PageLayout's XAML, the line numbers in the error changed. So the problem was there—but what was causing it?
Windows Debugging
One day, the app crashed while running outside of Visual Studio. Windows’ automatic memory dump feature saved our bacon—we had a crash dump to analyze! Using Visual Studio, we followed this MSDN guide. Two hours later… nothing new. The error was: Unhandled exception at 0x7582B152 (combase.dll) in triagedump.dmp: 0xC000027B: An application-internal exception has occurred (parameters: 0x055C31F8, 0x00000004).
I also got stuck because I didn’t have the Debugging Tools for Windows—a 1GB download wasn’t happening at work. But it might have been a blessing in disguise. Still, I found this helpful Wintellect video on OS-level debugging.
The Birth of Heather
After hours of manually triggering the crash by tweaking XAML and navigating screens (and risking carpal tunnel syndrome), I thought: Couldn’t I automate this? I didn’t need clicks—I just needed page navigation.
So I created a minimal Universal App with a single page, copied PageLayout (300 lines of XAML), and added a button that auto-navigated between pages. You can see the result here.
I named it Heather Speed Crash—and it delivered. It reproduced the crash reliably, reducing 20+ clicks and 5 minutes of manual work to one click in under 60 seconds. That made debugging far more efficient. Plus, the codebase was now <500 lines (vs. the original’s thousands).
Through further refinement (this version), we narrowed it down to PageLayout itself—not something it used. Intermittent bugs are painful—but the trick is reproducing them faster.
Two Lines of XAML
Between debugging and diving deeper, I realized I was stuck. So I posted the issue on Stack Overflow and, days later, the MSDN forums. Writing it out systematically didn’t reveal the answer this time—but on MSDN, someone suggested isolating the problematic ContentPresenter.
With Heather, I could test this:
- Commented out all four ContentPresenters—it worked. So the bug was in one of them.
- Uncommented them one by one—only two caused crashes. Now we were down to two lines of XAML.
Those two weren’t used on every page, so their Content was bound to null by default. That was the only difference. I set a default value for each—the crashes stopped. Oddly, if I set a default for just one and left the other null, the issue also resolved.
The root cause? A deep XAML layout bug triggered when two ContentPresenters with null Content coexisted on a page. During layout calculations, the engine crashed trying to size controls with null content.
The fix: Set both ContentPresenters to Visibility="Collapsed" by default and only make them visible if they have content.