In the 1940s, when one of Admiral Grace Hopper’s programs failed to work correctly, she discovered a moth stuck between the relays on the Harvard Mark II—and the term “bug” was born. Today, of course, debugging has nothing to do with insects. It’s all about the process of finding and removing defects in software.
Despite the fact that today’s programming languages and tools go a long way toward helping developers write robust code, there’s no protection from logic errors. Modern compilers can only perform rudimentary checks against programming language syntax and proper use of the type system. The compiler does little to help you determine the actual runtime behavior of your application. That’s where debugging skills are essential. This article will focus on debugging Windows Store apps and explore some of the techniques used in the field.
We’ll be using Visual Studio 2013 Preview, though these techniques will generally work with earlier versions of the product. Before getting started, however, you’ll need to prepare your environment for more advanced debugging than Visual Studio alone provides. We recommend downloading and installing the following resources:
- Windows 8.1 Preview: bit.ly/12nmBEg
- Visual Studio 2013 Preview: bit.ly/1aMpbeM
- Hands-on labs for Windows 8: bit.ly/QHh0JR
- Background task sample (Windows 8.1): bit.ly/IZpfqN
- Windows SDK for Windows 8.1 Preview: bit.ly/1cM9pyQ
- JustDecompile: bit.ly/qXxKJs
- Process Explorer: bit.ly/fzWyfq
Process Lifecycle Management
With typical desktop applications, the user launches an app and it runs until he terminates it. The application continues to run even when it’s not in the forefront. Windows Store apps are a bit different. When an app isn’t in the forefront, a Windows Service—the Runtime Broker—suspends all threads in the app, and wakes them back up only when the app is in the forefront. This novel feature helps preserve overall system performance and battery life. With Windows 8.1, even when an app is closed by the user, the default action is to place the app into a suspended state and not terminate it. If you prefer the older Windows 8 functionality, you can set Windows.ApplicationModel.ClosePolicy.TerminateOnClose equal to true.
Both Suspend and Resume events are sent to the app, giving you the opportunity to store and retrieve state or take other actions as needed. In addition, if an app applies too much memory pressure or takes too long to start up, the Runtime Broker will terminate the app, killing all threads. Visual Studio automatically disables Process Lifecycle Management (PLM) for apps that are being debugged, whether you’re debugging your own app or attaching to an installed app (using Debug | Debug Installed App Package). It’s important that PLM is disabled because it would prevent you from being able to properly debug an application. The reason is simple—the Runtime Broker may step in and terminate your application before you have a chance to properly debug it.
However, some of the debuggers outside Visual Studio, such as Windows Debugger (WinDbg) and Microsoft Console Debugger (CDB), require you to manually disable PLM features. To manually disable PLM, you can use the PLMDebug tool available in the Windows 8.1 SDK. PLMDebug is a command-line tool that allows you to disable PLM for a specific .appx package using the /enableDebug switch. You can view all installed app packages via the Windows PowerShell command Get-AppxPackage or via Process Explorer (as described later in this article) to identify the specific .appx package ID.
PLMDebug has several handy features. For example, it lets you explicitly send a variety of events to your app, including Suspend, Resume, Terminate, Force-terminate and Clean-terminate. It also allows you to attach a live debugger (which we won’t cover in this article).
Visual Studio also lets you trigger Suspend and Resume events, using the Debug Location toolbar, which isn’t visible by default. You can add it by selecting View | Toolbars | Debug Location. The debugging options will be enabled once you’re actively debugging your app. Figure 1 shows the Debug Location toolbar in Visual Studio 2013 Preview.
Figure 1 The Debug Location Toolbar
Many scenarios, such as updating a live tile, can be accomplished without using a background task, but sometimes background tasks are necessary and they represent another way in which code in your Windows Store app can be started implicitly due to specific system conditions you define. For example, you might want to add or create thumbnails in the background for one of your applications, but you only want to do it when the device is using AC power. The Maintenance Trigger allows you to start some tasks based on time intervals and system conditions, and to execute the tasks repeatedly. Although the code for background tasks is defined within your app, in most cases it’s executed by a separate process named BackgroundTaskHost.
A Windows Store app registers its background tasks with the OS-level background-task infrastructure by using the BackgroundTaskBuilder class. The background task is created as a class that implements the IBackgroundTask interface, and you simply need to implement the Run method. A background task must have exactly one trigger and one or more conditions set that describe the exact circumstances in which to launch the background task. The trigger is specified with the SetTrigger method of the BackgroundTaskBuilder class.
Visual Studio makes finding and debugging registered background tasks easy, because the Debug Location toolbar will show your application’s declared background tasks and allow you to start them through the Visual Studio visual interface. This technique works for starting all background tasks, except those that use ControlChannelTrigger, PushNotificationTrigger or a SystemTrigger with the SmsReceived trigger type. For more information, see the “Introduction to Background Tasks” white paper at aka.ms/O35jqc. And you’ll find a good code sample at bit.ly/IZpfqN.
There are many ways your app can be launched depending on what you’ve implemented, such as File, Protocol, PrintTaskSettings or ShareTarget. For example, the ShareTarget activation type would be active when a user shares something from another app to your app.
There have been some changes in Windows 8.1 regarding activations. Search activation, for example, has been deprecated, but there’s still some backward-compatibility support. There’s also a new, innovative approach to launching other applications that share the screen with your app. This means you can share the screen with a browser while your app is still active. You’ll find more information on this capability at bit.ly/11ckVS3.
To debug your application from any of these types of activations, your first step is to go to your application project properties Start Actions. Start by right-clicking on the ContosoCookbook in the Visual Studio Solution Explorer and choosing Properties. Select the checkbox “Do not launch, but debug my code when it starts,” as seen in Figure 2. With this setting you’ll be able to debug your application and place breakpoints in your OnLaunched handler that will be triggered when activated by any of the other activation types. This setting tells the application to get ready for debugging but not actually launch when you start a debugger session. The application will simply wait.
Figure 2 Setting Debugger Properties
Exploring a Running Application
Process Explorer provides some useful features for when you want to get a peek at the inner workings of a running application. To see these features, we’ll explore some of the code in an app called Kids Car Colors, which you can download from bit.ly/YnmAxT. Go to the Start screen and start the Kids Car Colors app, then start Process Explorer (assuming you’ve previously set it up).
If you expand svchost.exe, you’ll see the Runtime Broker and any executing Windows Store apps, as shown in Figure 3. By right-clicking on KidsCarColors.exe, you can view the properties, such as the root folder installation.
Figure 3 Process Explorer from SysInternals
The Properties window of an application in Process Explorer provides a wealth of information. For example, as Figure 4 shows, the Image tab lets you view the location of a given installed app. Both built-in apps and applications downloaded from the Windows Store always install in the [Root Folder]\Program Files\Windows Apps folder.
Figure 4 Properties of the Kids Car Colors App
You’ll also find the .NET Performance tab useful; it provides basic performance counter information, including such things as heap sizes, the number of Gen 0 Collections and the percentage of Time spent in garbage collection (GC). Looking at these performance counters allows you to evaluate the effectiveness of the GC, which is the mechanism that frees memory when objects are no longer referenced. It may be necessary to modify an application’s code to more aggressively free memory when it’s not needed. You can learn more about .NET performance counters at msdn.microsoft.com/library/w8f5kw2e.
You may need to change the ownership and permissions of the C:\Program Files\Windows Apps folder so that you can view the applications inside of it.
Inside C:\Program Files\Windows Apps, parallel folders exist for each of the installed applications. Each of these application folders has a wealth of information, as described in the next section.
Exploring the Code
As noted, you can go to the install directory for individual applications and find a great deal of information about the application, such as all the MP3 files (if any), images, XAML files and other resources. However, you won’t be able to examine the XAML files for Windows 8.1 applications, as they’ve been compiled into a binary. But there’s a variety of tools that lets you decompile the Windows Store app executables written in C# and Visual Basic .NET.
We’ll decompile KidsCarColors.exe using the JustDecompile tool from Telerik. Decompiling is the process of taking an application binary and generating readable source code. To do so, simply navigate to the app’s install folder as explained previously, right-click on KidsCarColors.exe and choose Open with JustDecompile. As shown in Figure 5, you can now see low-level details of the code revealed by the decompiler. Note that the data model inside the application is easy to decipher and browse. JustDecompile makes it easy to recover lost source code or peer into assemblies to discover the root cause of an external bug. This means you can view the source code of practically any installed Windows Store application.
Figure 5 Decompiling KidsCarColors.exe
It’s remarkable how much information is available with this tool. In creating Kids Car Colors, it took some effort to get the audio to work well when a kid clicked on the car color. But all of that code is exposed. If you navigate to the ItemDetailPage object in the JustDecompile project explorer, you’ll be able to discover exactly how the sound files are played: retrieving the MP3 from local storage, instantiating various MediaElements, registering media callback events, calling SetSource and so on. For anyone wanting to replicate this approach, it’s all there, exposed to the world.
JustDecompile provides a few buttons on its toolbar, including the Assembly List button, which allows you to explore the references the application has set. Just knowing what references a Windows Store application has set tells you something about what functionality the application uses. For example, you can see that Kids Car Colors leverages the Advertising SDK. That makes sense, because the app does show advertisements. Theoretically, however, you could set a reference to an assembly that you never use. Imagine that we removed the advertising inside the app but forgot to remove the reference to the Advertising SDK assembly. JustDecompile enables you to see exactly which version is running out in the wild and what the code and references look like.
JustDecompile also includes a feature called Find Usages, which allows you to replicate the Find All References command in Visual Studio. You can simply ctrl-click on any Namespace, Type or Member in your decompiled code to get a list of all corresponding code references. This can be a tremendous help in learning about how an application works without having any source code.
To maximize your effectiveness as a Windows Store app developer, you need to have a good understanding of how to debug applications. This article gives you a brief overview of some tools and techniques you can use to find and fix problems in your code. Moreover, some of the techniques can help you learn how other Windows Store apps work, even if you don’t have the source code.
Bruno Terkaly is a developer evangelist for Microsoft. His depth of knowledge comes from years of experience in the field, writing code using a multitude of platforms, languages, frameworks, SDKs, libraries and APIs. He spends time writing code, blogging and giving live presentations on building cloud-based applications, specifically using the Windows Azure platform. You can read his blog at blogs.msdn.com/b/brunoterkaly.
Robert Evans is a premier field engineer and the technical lead for Windows 8: Windows Store App Labs. He’s a Microsoft Certified Professional Developer and a Windows 8 Dev Bootcamp Master Instructor. He has presented at TechReady, GeekReady and The Tablet Show, and hosted the Windows 8 Hardware Lab at the Microsoft Build conference in addition to numerous Windows 8 Hackathon events. Prior to becoming a premier field engineer, Evans spent 12 years as a software development engineer at Microsoft working on various products such as Xbox Live, MSN and Mobile Engineering in Microsoft IT. You can read the Premier Field Engineering blog, to which he contributes, at aka.ms/Utg864.
Thanks to the following technical expert for reviewing this article: Christophe Nasarre-Soulier (Microsoft)
Christophe Nasarre works on a development support team at Microsoft. Since 1996, he has worked as a technical editor on numerous books and written several articles for MSDN Magazine.