Remote Debug with Visual Studio 2010

Disclaimer:

  1. This tutorial was successfully tested with two Windows XP SP3 32 bits boxes (both with the latest updates), and also with a Windows 7 Professional 32 bits box together with a Windows XP 32 bit box. Other combinations might not work, or might need extra configuration.
  2. Both machines were hosts of the same organizational intranet (LAN). I guess it's possible to do this across networks, but it's a quite more complex scenario, mainly security-wise; firewall configuration and VPN establishment are the minimum hurdles I can think of. Therefore, we'll stick to a LAN this time.

To make things shorter, let:

  • VS: Computer where we'll run Visual Studio in order to perform remote debugging.
  • RE: The remote machine, where the program to debug will run.

With all this in mind, the steps are the following:

  1. Both boxes must have a user account with the same user name and password. In VS, we'll run Visual Studio under that account, and in RE, we'll run the program to debug under an account with the same user name and password. Both accounts must have Administrator rights; this may be done using limited accounts, setting policies and permissiones appropiately, but I'll leave that to someone else.
  2. In VS, make sure no other account is running Visual Studio (or at least it has a different solution open), log into the "shared" account, launch Visual Studio and build the app in Debug mode. If you use strong naming for your managed assemblies, you might need to reenter their keys for every assembly. It's a downer, but you'll only have to do it once, so bear with it.
  3. Once the app builds successfully, share the folder where the debug binaries reside (typically, somewhere like ProjectName/bin/Debug). This can be achieved by right-clicking the folder and going to the Sharing tab of the Properties option:
    After selecting "Share this Folder", click "Permissions", and grant full control permissions to the shared account. If it doesn't appear, click "Add" and add it first.
  4. Go to RE and check that the shared folder can be accessed.
  5. Still in RE, go to Control Panel->Administrative Tools->Local Security Policy->Security Options->Network Access: Sharing and security model for local accounts and select the Classic - local users authenticate as themselves option. This will allow remote login from VS.
  6. In RE, launch Internet Explorer, go to Tools->Internet Options->Security->Trusted Sites->Add this website to the zone and add the shared folder as a trusted site::
    In the screenshot above, desarrollo3 and precision are two development boxes we configured for remote debugging (two different VS).
  7. In RE, make sure that the .exe.config file associated to the app's .exe contains the following tag:
    If we don't do this, when we try to run the app in RE, we'll get a message box telling us to apply that setting.
  8. In RE, run the app's .exe that resides in the shared folder. It's vital that it can run successfully by itself, or remote debugging won't work. The first problem you'll run into will be that, if your app uses native C++, the debug assemblies from the C++ runtime won't be available in the remote machine (because it doesn't have Visual Studio installed), so you'll get EEFileLoadException or something like that. You can use Dependency Walker to see which assemblies you need, and copy them from VS to RE. This gruesome task can be simplified by creating a deployment project in VS which packs those dlls in a .msi file which you will run in RE. The details for this will be in a future post (this one is long enough already...).
  9. In VS, look for the Remote Debugger folder (in my case, it was located in C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE) and copy it or share it to RE. I copied it inside the Debug shared folder.
  10. In RE, go to the Remote Debugger folder that was shared/copied in the previous step, and run msvsmon.exe. Go to Tools->Options, and in the Server Name text box, enter the shared account user name followed by @ and RE's name. Select Windows Authentication, click Permissions and grant Debug permissions to the shared account. Once this is done, in msvsmon's output window, you should a message like "Msvsmon started a new server named shareda_account_user_name@RE_s_name. Waiting for new connections...".
  11. In RE, run the .exe from the shared folder.
  12. In VS, from Visual Studio, go to Debug->Attach to Process. In this form, in the Qualifier text box, enter the Server name you entered in msvsmon. If the connection is successful, in the text box below you'll see a list of the processes running in RE. Otherwise, you might get errors saying you can't connect to msvsmon because the authentication failed. In that case, you'll need to configure Windows Firewall (or whichever other firewall you're using) on both boxes to allow an exception for msvsmon, both pointing to the msvsmon.exe file inside the shared folder. In order for Visual Studio and msvsmon to notice these changes, you might need to restart them. As a last resort, and under your own risk, disable the firewalls.
  13. If the attachment succeeds, you can now set breakpoints, check the Output window, etc.
  14. Unsheath your sword and start slaying bugs. If the project is a monster like ours, with more than 100 projects, managed and native in different languages, it's likely that after 5 or 10 debug steps, Visual Studio's debugger will hang and you'll have to click the stop debugging button. Therefore, you might have to place a single breakpoint very wisely so you can solve the problem in a single break (think very well where to stab your sword at). Happy remote slaying!

Comments

Popular posts from this blog

VB.NET: Raise base class events from a derived class

Apache Kafka - I - High level architecture and concepts

Upgrading Lodash from 3.x to 4.x