Debugging .NET Native Windows Universal Apps
July 29, 2015
With the release of Windows 10 we also shipped Visual Studio Tools for Windows 10. As you will have heard Universal Windows apps written in .NET (either C# or VB) will be compiled to native machine code before being deployed to customer devices using .NET Native. However, the default Debug configuration still uses .NET Core runtime to allow for a fast edit->compile->debug cycle. You always need to test with the actual code generation and runtime technology your application will use when running in production as it can expose bugs you might not be able to find with your development configuration (e.g. race conditions that manifest due to different performance characteristics). To facilitate this, when you choose the Release build configuration your app is compiled using the .NET Native tool chain.
If you don’t find any issues with the .NET Native build of your application, great! However if do you run into any issues that require you to debug there are a few things to note:
- When you are debugging an app built with the .NET Native tool chain you will be using the .NET Native debug engine which has some capability differences from normal .NET debugging
- The Release configuration will be using code optimizations that will impact debugging
- Variable inspection of runtime types will be slightly different
Code optimizations
If you run into an issue when testing the Release configuration that you need to debug it is important to note that the Release configuration is by default fully optimized code (e.g. code inlining will be applied in many places). These optimizations will have a significant impact on the debugging experience including unpredictable stepping and breakpoint behavior (due to code inlining) and the inability to inspect most variables due to memory optimizations.
This means you will want to debug a non-optimized .NET Native build. This fastest way to do this is simply to disable optimizations (covered below), however we recommend creating a new build configuration so your existing Debug and Release configurations continue to work the way you expect. To do this open the “Configuration Manager” from the build configuration dropdown.
Then from the “Active solution configuration” dropdown choose “<New…>”
Give it a name you will understand (e.g. “Debug .NET Native”) and choose “Copy settings from Release” and click “OK”
Open the project’s property page, and on the build tab uncheck “Optimize code”
You now have a build configuration you can easily switch to for debugging .NET Native specific issues. Assuming you can reproduce the issue with the non-optimized build this will yield a much better debugging experience.
Inspecting Runtime Types
One thing that will be different from debugging normal JIT based .NET applications is that when inspecting objects from the Windows Runtime (including XAML UI Elements) you will see a “[Native Implementation]” node. In order to inspect the elements properties you will need to look under this node (this is due to the fact that these objects are actually implemented in native code and are accessed via a thin .NET wrapper). When looking at this node, if you did not enable Microsoft Symbol Servers in your symbol settings you will see a message saying “information not available no symbols loaded for [module name]”. Right click on the “[Native Implementation]” frame and choose “Load Symbols”, the debugger will then download them from the Microsoft Public Symbol servers.
Once symbols are loaded you will be able to inspect the property values from the “[Native Implementation]” node. For example, to see the value of the “Text” property on a Textbox object you need to look under the “[Native Implementation]” node—this does mean that if you hover over “textbox1.Text” in the editor while debugging .NET Native you won’t see a DataTip.
Summary
You likely won’t need to spend much time debugging your code compiled with .NET native, but when you do remember to disable code optimizations and that many properties for runtime types will require looking at the “[Native Implementation]” node. As always we want to hear how the debugging experience is working for you, and how we can improve it. So please let me know in the comments section below, through Visual Studio’s Send a Smile tool, or via Twitter.
Seems like a lot of work. .NET feels hijacked and completely different from what it used to be. The Xaml is sub-par and now call-stacks are just a simple frame from the Curtain of COM. Gone are the days of knowing what caused an exception in your application (along with exploring and learning about a comprehensive, powerful framework). Top it all off that UWP is really Windows-only and not open-source/cross-platform like the rest of new Microsoft technologies, and you got yourself a real problem as a Microsoft client application developer. Where is the incentive to develop with this stuff now? You guys used to be cool and fun.. Applications were elegant and robust. Now there's… this. What happened?
– NET Native for desktop apps ? (XAML, WinForms, console, libraries)
– Possible NOT to use NET Native for uniwersal apps (W10) ?
Why not debug as a non-native assembly? msil debugging tools including the ones from MSFT are excellent. I don't get it.
@ Tristan – agree 100% We have been asking for native compiled code for WinForms for over 12 years! The lack of native code for these types of application is precisely why .Net failed for commercial offerings and found its niche as a good in-house code platform.
Thanks for the feedback all. As I stated in the blog post above .NET Native is primarily a compilation technology intended for use before deployment to production, but as in other scenarios you will want to test your application as there can be some differences. Only if you find a difference will you need to debug.
Regarding the future of .NET Native Visual Studio 2015 is limited to support for Universal Windows apps only, however the .NET team is looking into expanding support going forward. I would encourage you to engage directly with them via the .NET foundation site forums.dotnetfoundation.org
So what is the reason so many development effort is put in this? To compete with iPads?
Why not put it all into WPF that is used everywhere and is de-facto the way to make the Windows applications?
@Mikhail, WPF is a great framework for developing apps on the Desktop PC, but it is limited to x86/x64 Desktop versions of Windows. Universal Apps are intended to run on many end points beyond the PC. You can read more about Universal apps at msdn.microsoft.com/…/dn894631.aspx and I would encourage you to engage with the Windows team directly on their developer community sites dev.windows.com/…/community
I'm thinking hoping that this may be approaching build once run almost anywhere in the windows ecosphere that I was thinking on since the release of the first windows phone but these helpful debugging features and workarounds were already available in some previous versions. It seems that the team have further surfaced them and brought them to your attention. I would be more thankful 😉
And worst of all this practically killed F# portable classes. I wish this .net native is somewhat optional.
With .Net Native toolchain (Release) the UWP C# apps run pixel manipulations (With WriteableBitmapEx) much slower. Tried most of the suggested workarounds. Wish .Net Native was really faster !!!