Learning the secret of flight from a bird was a good deal like learning the secret of magic from a magician. After you know the trick and what to look for, you see things you didn't notice when you did not know exactly what to look for.
Debugging a problem that occurs on your own computer is easy—you know the exact configuration, you can look at the code in a debugger, and you can gather as much information as you need. But sooner or later, you have to release your software to customers. No matter how thoroughly you tested your program, your customers will find bugs you didn't know about. Sometimes you'll get lucky and be able to reproduce those problems. When that happens, great! You can debug those problems just as if they were discovered in normal development. But sometimes, you won't be able to reproduce the customer's bug on your computer. Debugging that problem at a remote customer site is a much tougher nut to crack.
At its core, debugging is merely reasoning logically about a problem (see Chapter 3). In that sense, debugging a problem on a customer's machine shouldn't be very different from debugging a problem on your own machine. But in actual practice, the two forms of debugging tend to be very different. You are limited in the number of techniques you can use remotely, so you must compensate in other ways.
In this chapter, we'll discuss some of the reasons why debugging issues at a remote customer's site is hard. We'll talk about the customer's perspective and expectations, and then we'll address some techniques you can use to ease the process. Finally, we'll end with a discussion about one of the most common causes of unreproducible customer bugs, .NET security.