Chapter 19. Debugging .NET Applications

In This Chapter

Debugging in any environment is an art. It requires a thorough understanding of the environment and the tools available. With the CLR, you are able to devote more time to the application and less time to “programming details.” When a problem arises, you need to understand as much as possible about certain key features of the CLR to be able to diagnose and solve the problem.

When I took one of my first programming classes, I had to build a traffic signal. The traffic signal was to run through the sequence of green, yellow, and red. It also had to take input from a crossing signal so that the sequence could be altered somewhat to take into account a pedestrian who wanted to cross. What I remember about that project is how much time I spent worrying about how I was going to archive and retrieve my program (from cartridge tape), interpreting the cryptic error messages that the assembler returned, and figuring out how I was going to move blocks of assembly code in case the function took more statements than I had accounted for. I spent little time on the problem of sequencing the lights and a lot of time on the “mechanics” of the environment. Debugging in such an environment usually meant making sure I had not moved the code to the wrong place, that all of the references to the moved code had been correctly updated, and that I was testing the correct bit. Memory was simply a place where the code was not. I relied heavily on interrupt service routines for timing and scheduling.

The next generation found me dynamically allocating memory, but I was still limited by the amount of physical memory that was available. DOS extenders allowed more memory to be addressed, but there was still a fixed size of physical memory of which the programmer was aware as the software was developed. Although many of the problems associated with the “assembly” era were abstracted away from the programmer, memory was still an issue. The programmer had to be aware not only of how much memory his program used, but in general, he had to be aware of how much memory the system was using.

With the advent of virtual memory, the programmer worried less about how much memory was installed or available. It became common to not even check the return of malloc or new (in C or C++ code) because it was assumed that more memory was always available. The programmer now had to be concerned with page faults and swap space. Typically, a program did not run out of memory—it just got slower as more time was spent swapping portions of the program to disk. While the programmer worried proportionately less about memory, advances were also being made in scheduling of the CPU.

It was possible for an errant program to “take over” the CPU. If my program did not play nicely in the sandbox and spin in a tight loop, your program was affected. With pre-mptive multitasking, one program was less likely to affect the operation of the whole system. The operating system also made it appear as if many processes were running in parallel.

After it was possible for every process to be run “at the same time,” the programmer wanted finer grained control over how his program was scheduled. Threads essentially became a unit of scheduling over which the programmer had control.

With each new generation or paradigm shift, the problems of the previous generation remained, although they were largely abstracted away from the programmer. The tools available to debug a program also changed as well. The tools had to give the programmer the information that was specific to the environment. With physical memory and interrupts, good tools would allow the programmer to see how much memory was used up and how often and which interrupt service routines were being executed. With virtual memory and threads, terms such as working set size, thread count, and CPU usage became important.

With the CLR and the .NET Framework, concepts such as type, value, assembly, and application domain become important. To effectively debug in this environment, the tools must reflect information and statistics about these new concepts. That is the focus of this chapter: to familiarize you with the tools that are available to glean information from the system about these new terms. After you understand these tools and facilities, you can combine them as the art of debugging.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.94.171