Visual Studio Remote Debugging and PDB Files
Thanks for all the comments and emails about my blog entry, PDB Files: What Every Developer Must Know. There was lots of nice feedback, but more importantly great questions! Instead of responding in the blog comments to these questions as I normally do, a couple of the questions were important enough that I wanted to make full blog entries out of them. Please continue to ask any questions you have about PDB files as I am taking it as my personal mission to ensure that everyone developing for Windows knows exactly how to use PDB files!
The first question I want to cover is from Eric Hill:
Thanks for the deep dive on PDB files. You're exactly right, all the information you have provided probably exists somewhere, but not all together.
I suspect the information you've provided explains a problem I had recently doing remote debugging I copied my private build to another machine, with PDB file right there with it, but when I remote-debugged, VS could not find any of my breakpoints. Just on a hunch, I moved the executable files on the remote machine such the path was the same as where the files were on the build machine, and that fixed the problem. But that doesn't seem like a very reasonable requirement. What approach would you take to remove this restriction for remote debugging?
For the most part, remote debugging works well. However, the one thing I haven't found discussed in the Remote Debugging documentation is where the PDB files are loaded, which is the crux of Eric's issue.(For the rest of this article, I'm assuming you've read all the remote debugging documentation.) To make everything clear, let me define two terms; the remote machine is where MSVSMON.EXE and your application execute and the local machine is where the Visual Studio IDE is running. The key trick to know about remote debugging is for .NET binaries, the PDB files are loaded on the remote machine and for native binaries, the PDB files are loaded on the local machine.
From Eric's question, I'm betting he was doing native remote debugging because when he moved the binaries to the same path on both machines, everything worked like expected because it was Visual Studio found the binary on the local machine and in turn, the PDB file as I described in my previous blog entry.
If you want to verify where the PDB files load, here's how I verified the loading. Set up remote debugging for a console application using your favorite language. Put the project in the same drive and directory on both the local and remote machine. Start single stepping with Visual Studio and stop at the entry point of the application. Run Process Explorer on both machines and in each press CTRL+F to search for handles and DLL strings. Enter "PDB" and click the Search button. Here's a screen shot from the local machine where I was remote debugging to a native C++ application:
With Visual Studio doing the symbol loading for native remote debugging, both local build and public build symbols load where you expect them to load. It's a little more interesting for .NET binaries for remote debugging. For your private builds, you'll copy the binary and matching PDB file to the remote machine where the loading occurs. What about the public build PDB files for .NET binaries?
As all .NET PDB files are loaded on the remote machine, the public build PDB files are loaded there as well. In order to get them you have to set the _NT_SYMBOL_PATH environment variable to point to your symbol server. If you don't want to do that manually for forty test systems, you can use the PowerShell script I wrote to automate the process. Once you have the _NT_SYMBOL_PATH set on the remote machine, when you start remote debugging, Visual Studio will let you know that it will be downloading public symbols to the remote machine:
With remote debugging, if both machines have the local build binaries in the same drive and directories, life is easy because the symbol loading occurs without you having to worry about the type of development you're doing. Eric asks if that's a reasonable requirement. Well, I don't have a real answer other than to say that's just kind of how it is, especially for native code. I wanted to provide the background as to how remote debugging worked so you would understand the limitations and ramifications.
Please keep the questions about PDB files coming!
Personal note: I have to let everyone know that Eric Hill, who asked the above question, had a huge influence on my career. Way back in 1992/1993 he was punished for some horrible past life transgression by being stuck with me as a lab partner for CSC 311 (Computer Organization and Logic) at North Carolina State University. That was the killer death class in the CS curriculum that everyone dreaded as it was electrical engineering for CS majors. Back in those days, you were handed a breadboard, an Intel 8051CPU, a bunch of wires and you truly built a computer, none of that easy simulation garbage they have today. Eric's brilliant (he got an A+) and pulled my stupid butt through the whole class (and I was thrilled with my C-). Oh, he also kept me from electrocuting myself a couple of times as well. When it came time for the end of year project, where we had to do something real, like control hardware devices, with our hand built computer we didn't want to have to unplug all those wires we had carefully gotten working. Eric had the brilliant idea of doing a PROM-based debugger as our project. It was all software and much easier than anything else we could have done. As you can guess, all my interest in debuggers stem from that wonderful project. Thanks, Eric!