For the second time I have had the privilege of being one of the reviewers for another debugging book. This time I’m referring to Mario Hewardt’s new book: Advanced .NET Debugging.
It was a great learning process. After months of reviewing chapters and source code and giving suggestions, I feel my .NET debugging knowledge is not the same. It is much better now!
Let me tell you why I’m so thrilled with this book.
First of all, this book discusses in depth several tools used by our product teams when isolating internal bugs from .NET application and also the tools used by CSS (Customer Service and Support). In case you ask, they are all public tools!
Also the book gives a deep and clear explanation about the CLR (Common Language Runtime). In my opinion, that is one of the most important parts of the book. If you are starting with .NET Debugging, you may be familiar with some of the SOS commands. That’s the easy part. However, if you want to improve your skills as a debugger you must go deeper and understand the CLR internals, like method table, method descriptor, memory management, etc. The chapter about CLR explains the internals in a superb way, and it’s my favorite!
If you’re new to debugging, you’re going to like the chapter about Basic Debugging Tasks. It’s didactic enough for beginners, demonstrating how to use the most used commands and how to get useful information from basic commands.
Another part of the book talks about more complex scenarios and technologies. It’s a deep explanation! You’re going to learn a lot about Managed Heap, Garbage Collection, Thread Synchronization and Interoperability. Based on my experiences helping customers from different countries, I can tell you the number one application problem from .NET applications: memory issues. I know it’s ironic since GC is supposed to manage memory, so let me explain: GC does the job very well. The problem is mixed code: managed and native. The GC only has control of the managed code. The book explains it very well, and there are lots of sample codes reproducing different issues scattered among the chapters. This is cool because you can use the sample code to apply the knowledge while debugging specific scenarios.
Like Mario’s previous book, this one is also very pragmatic. You won’t see those situations that are unlikely to happen on a production server, actually the opposite: you’ll see issues that we face on a daily basis with the approaches, techniques and tools we use when debugging these issues. Very helpful!
"Fortunately, Mario's book combines just the right amount of explanation of the runtime to help you understand the thought process and the techniques he uses to solve problems with many practical and clever tricks learned from debugging real world applications. So if you want to quickly get up to speed debugging your CLR applications, this is definitely the book to read. It covers many aspects of debugging managed applications—in particular, it gives insights into areas that are hard to diagnose such as thread synchronization problems. The illustration of debugging techniques is largely done with examples which makes it easier to follow." (Excerpted from the Foreword by Patrick Dussud, Technical Fellow, CLR, .NET FX, Microsoft Corporation.)
Here is the index of the book:
Part I – Overview
Part I introduces the reader to the basic concepts required to efficiently debug .NET applications using the Debugging Tools for Windows package.
1. Introduction to the Tools
This chapter contains a brief introduction to the tools used throughout the book, including basic usage scenarios, download locations, and installation instructions. Amongst the tools covered are:
Debugging Tools for Windows
.NET 2.0 redist/SDK
Reflector for .NET
Managed Debugging Assistants
2. CLR Fundamentals
This chapter discusses the core fundamentals of the CLR. The chapter begins with a high level overview of the major runtime components and subsequently drills down into the details and covers topics such as:
· CLR and the Windows Loader. Discusses how .NET applications are natively supported using the PE file format.
· Application domains (system, shared, default, custom) as well as loader heaps etc.
· Assembly overview
· Assembly manifest
· Type metadata
· And more…
3. Basic Debugging Tasks
Chapter 3 gives hands on examples of the basic .NET debugging tasks such as:
· Thread management
· Display stack traces
· Display local variables
· Breakpoint management
· Dumping heap based objects
· .NET exception model and how to analyze in the debuggers
· Basics of postmortem debugging
· Remote debugging
Part II – Applied Debugging
Par t II is a practical approach to debugging common .NET problems encountered in the development process. Each chapter is dedicated to a specific CLR component and/or technology and begins by detailing the inner workings of that component. Subsequently, a number of common problems related to the specific technologies are discussed and how the debuggers and tools can be used for root cause analysis.
4. Assembly Loader
The complexity of .NET applications can range from simple command line applications to complex multi-process/multi machine server applications with a large number of assemblies living in harmony. In order to efficiently debug problems in .NET applications one much be careful to understand the dependencies of .NET assemblies. This chapter takes a look at how the CLR assembly loader does its work and common problems surrounding that area.
5. Managed Heap and Garbage Collection
While .NET developers can enjoy the luxury of automatic memory management, care must still be taken to avoid costly mistakes. The highly sophisticated CLR garbage collector is an automatic memory manager that allows developers to focus less on memory management and more on application logic. Even though the CLR manages memory for the developer, care must be taken to avoid pitfalls that can wreak havoc in your applications. In this chapter we look at how the garbage collector works, how to peek into the internals of the garbage collector and some common programming mistakes related to automatic garbage collection (non memory resources, memory fragmentation, finalizer problems etc).
A multithreaded environment allows for a great deal of flexibility and efficiency. With this flexibility comes a lot of complexity in the form of thread management. To avoid costly mistakes in your application, care must be taken to ensure that threads perform their work in an orchestrated fashion. This chapter introduces the synchronization primitives available in .NET and discusses how the debuggers and tools can be used to debug common thread synchronization problems. Scenarios such as deadlocks, lock contentions, sync blocks, thin locks and thread pool problems are discussed.
.NET relies heavily on underlying Windows components. In order to invoke the native Windows components the CLR exposes two primary methods of interoperability:
1. Platform Invocation
2. COM Interoperability
Since the.NET and Win32 programming models are often very different, idiosyncrasies often lead to hard to track down problems. In this chapter we look at some very common mistakes done when working in the Interoperability layer and how to use the debuggers and tools to troubleshoot the problems.
Part III – Advanced Topics
8. Postmortem Debugging
Quite often it’s not feasible to expect full access to a failing machine so that a problem can be debugged. Bugs that surface on production machines on customer sites are rarely available for debugging. This chapter outlines the mechanisms for debugging a problem without access to the physical machine. Topics discussed include the basics of crash dumps, generating crash dumps, analyzing crash dumps etc.
9. Power Tools
Introduces the reader to power tools such as Debugging via Powershell , IISDiag and more.
10. CLR 4.0
This chapter is reserved for any substantial enhancements coming out while the book is being authored/published.