Debugging on remote machines and tablets

For most developers, debugging an application means setting a breakpoint with F9 on a line of code, and then pressing F5 (or Debug | Start Debugging), and stepping into and over statements with F10 and F11.

This experience can work well when you are debugging code on your local machine, but what if you need to debug code running on a different machine that does not have Visual installed? This is where remote debugging tools come into play.

Even though many developers may not be aware of the functionality, debugging code on remote machines with Visual Studio isn't anything new. It's just that until now the debugging experience has been limited and unrefined. VS2015 builds on its predecessors, and the experience it provides is much improved as it combines improvement in speed with broader support for the wide range of devices that today's applications need to support.

Remote debugging is something every developer should know how to do, and this recipe shows you how to configure a machine for remote debugging, and then debug an application you have deployed to that machine.

Getting ready

For this recipe, you will need a second machine to act as your remote machine. It doesn't matter if it's a virtual or physical machine as long as your development machine and the remote machine can communicate over a network connection. This recipe assumes that you are running on VS2015.

The remote machine will need Remote Tools for Visual Studio 2015 installed before we begin. If you don't have Remote Tools already installed, download them from the Microsoft website at https://www.visualstudio.com/downloads/download-visual-studio-vs (look under the section Tools for Visual Studio 2015 | Remote Tools for Visual Studio 2015), and then install them. Versions exist for each CPU architecture that Windows supports: X86, X64, and ARM. This recipe assumes that your local machine has a premium edition of VS2015, but note that Remote Tools does support Express for Windows Desktop and Express for Windows.

Tip

Match the architecture of the Remote Tools to that of the remote machine's operating system. For best results, your development machine's OS should match that of the remote device.

There are several advantages to using Remote Tools. You will be able to debug on a remote machine that does not have Visual Studio installed, especially important for ARM-based devices such as the Surface RT where a native version of Visual Studio is not available. It also saves time and the hassle of maintaining a working development environment on each end-device you are targeting. Finally, remote debugging makes it easier to see how your application performs for end users by minimizing the influence of your development environment on your application's operation.

Note

At the time of this writing, those seeking to use the ARM-version of Remote Tools should use Remote Tools for Visual Studio 2015 Update 1. You can use Remote Tools Update 1 with VS2015 Update 2.

How to do it...

Now that our tools are in order, let's see how to perform remote debugging in practice through the following steps:

  1. Create a new C# console application using the default name.
  2. Open the Program.cs file, and fill in the body of the Main() method as shown in the following code excerpt (there is an intentional bug in the code):
    static void Main(string[] args)
    {
      Console.Out.WriteLine("Press any key to begin");
      Console.ReadKey();  // Wait for keypress to start
      var charCode = 97;
      var outputBuilder = new StringBuilder();
      for (int i = 1; i < 26; i++)
      {
        outputBuilder.Append((char)(charCode + i));
      }
      var output = outputBuilder.ToString();
      Console.WriteLine(output); // should write "abcd...z"
      Console.ReadKey();
    }
  3. Run the program locally by pressing F5. When the console window appears, press any key and you should see a string of characters appear. Press any key again to close the program.
  4. You should now check if it works on the remote machine. On your remote machine, start Remote Debugger Configuration Wizard, and ensure that the Run the Visual Studio 2015 Remote Debugger service checkbox is deselected.
    How to do it...

    Tip

    Since our recipe uses a Console application, we do not need to run the remote debugger as a service. The Remote Debugger service is useful when working with web applications or in a known secure environment. More on this later.

  5. Also ensure that the firewall configuration is set as appropriate for your network, and then complete the remaining steps of the wizard by taking the default values. The following screenshot illustrates the firewall settings we have selected:
    How to do it...
  6. Now that you have finished configuring it, start the Remote Debugger on your remote machine.
  7. When the debugger appears, you should see a message showing the machine name and port number that the debugger is listening on. Take a note of the machine name as you'll be using it later on. In the following screenshot, the machine is named DESKTOP-SVJA20M, and it is running on port 4020:
    How to do it...
  8. For the smoothest development and debugging experience, the remote machine should be configured to run the code from your development machine via a network share. Either add a specific share to the bindebug folder of your development machine, or access it via the inbuilt C$ share, for example, \dev-machineC$UsersJeffDocumentsVisual Studio 2013ProjectsConsoleApplication1indebug (your location will vary).

    Tip

    Ensure that you can connect to your network share from the remote machine. Code Access Security is not applied to .NET 4.0 applications by default, but it is for .NET 2.0 applications. To debug a .NET 2.0 application on a remote machine via a file share, you need to make sure the share is a trusted location. Use the caspol.exe utility for both the x86 and x64 versions of the framework to modify the security settings of your machine (settings are maintained separately for each CPU architecture). For more details, refer to https://msdn.microsoft.com/en-us/library/cb6t8dtz(v=vs.110).aspx.

  9. In Visual Studio on your development machine, open the project properties by right-clicking on the project in Solution Explorer and selecting Properties. Select the Build tab.
  10. Under the Output section, set Output path to the network share on your remote machine, as shown in the following screenshot:
    How to do it...
  11. Build your solution so that the debug build of the application is deployed. Then return to the Properties dialog, and switch to the Debug tab.
  12. Change Start Action to Start external program, and enter the path to the compiled application using the path that will be used by the remote machine to start the application, for example, \dev-machinesharenameConsoleApplication1.exe.
  13. In the Start Options section, check the Use remote machine checkbox and enter the name of the remote machine. This is the machine name you noted in Step 6. Your Debug tab should now look similar to the following screenshot:
    How to do it...
  14. On your development machine, press F5 to start debugging. Assuming there are no firewall issues and your permissions are okay, Visual Studio will communicate with the remote machine and launch the application for you automatically. Note that, depending on the accounts used on each machine, you may be prompted for login credentials. If that happens, enter the details of the user running the debugging monitor on the remote machine.
  15. If you have a problem communicating with the remote machine, check that the firewall on the remote machine is allowing incoming connections. If it isn't, you can either rerun Remote Debugger Configuration Wizard to confirm the firewall settings, or manually add a rule to allow a connection on the port number the Remote Debugger is using (the port number is shown in Step 6).
  16. If you switch to your remote machine, you should see that the application is running and displaying a console window with its output, and Visual Studio 2015 Remote Debugger reflects that a debugging connection has been made. The following screenshot shows the updated debugger:
    How to do it...
  17. The application is now waiting for you to press a key. Before you do, set a breakpoint on your development machine in the Main() method of Program.cs, somewhere after the ReadKey() method. A good place would be where the outputBuilder variable is initialized.
  18. Return to the remote machine, and press a key to continue program execution.
  19. Switch back to the development machine. You should find that your breakpoint has been hit, and that the application is ready for you to continue debugging.
  20. Step through the code in Visual Studio to get a feel of how quick the remote debugging experience is, and then continue execution down to the second Console.ReadKey() statement. The easiest way to do this, rather than looping through the for loop 26 times, is to right-click on that second Console.ReadKey() statement, and select Run to Cursor.
  21. You may notice that the output has dropped the a at the start of the output string. Is that a display problem or a bug in the code? You can check the string length to be sure. Navigate to the Immediate window and type ?output.Length to see how long the output string is.
  22. If the Immediate window isn't visible, you can display it by pressing Ctrl + Alt + I or choosing Debug | Windows | Immediate from the menu.
  23. You should see the value 25 displayed, as shown in the following screenshot:
    How to do it...
  24. Note that this value is not from a process on the local machine, it is from the process running on your remote machine. To verify this, navigate to Debug | Attach to Process from the menu bar. In the Qualifier drop-down menu, select the remote machine. (If it does not appear, use the neighboring Find... button). It will be suffixed by the port number that the remote debugger is listening on. When the Available Processes list is populated, you should see that your application is the only process on the remote machine that the debugger is attached to (titled Ch5-RemoteDebuggingWin10.exe in the following screenshot):
    How to do it...
  25. Stop debugging by either pressing Shift + F5, clicking on the stop button in the debugging toolbar, or choosing Debug | Stop Debugging from the menu. This will also terminate the process on the remote machine.
  26. Since we have the project open already, fix the bug in the for loop by altering the loop variable to start from 0 instead of 1. Your for loop should now look like the following code:
    for (int i = 0; i < 26; i++)
    {
      outputBuilder.Append((char)(charCode + i));
    }
  27. After making the changes and saving your work, press F5 to start debugging again. Visual Studio will compile the application, and launch it on your remote machine for you.
  28. Complete the execution of the application to verify that the output is now correct.

How it works...

The main thing to keep in mind when using the remote debugger is that you are looking at data from the remote machine. The debug experience can feel so smooth and transparent that it's easy at times to forget that a path name for a file, for example, is a path relative to the remote machine and not your local machine.

Normally, the debugger runs using Windows Authentication; however, it can be switched over to the No Authentication mode. The No Authentication mode enables debugging scenarios for managed and native debugging across versions of Windows that were previously not possible. The danger of this approach is that it opens up a security hole including allowing attackers to launch any application they choose. Be sure not to run the remote debugger on production machines in this way. The remote debugger is a developer tool, and should only be run when developers require it.

There's more…

If you don't want to install the remote debugger on the remote machine, you can run it directly from a file share. However, you won't be able to debug Universal Windows applications in the Windows Store or debug JavaScript this way.

Another thing to note is that when you are debugging a UWP app on Windows 10, you will not need to change the Start Action section of the project to start an external program. Leaving it set to Start project, and then ticking the checkbox and setting the value of the Use remote machine field will tell Visual Studio that the project should be packaged and deployed to the remote machine before debugging commences.

Debugging an ASP.NET process

To debug ASP.NET websites running under IIS, you do not need to make any changes to the project properties to configure the remote debugger. In fact, you can't. The options aren't available.

For remote debugging, you will either need to run the remote debugger as a service, or run the application as an administrator. On your development machine, you then use the Attach to Process dialog to connect to the ASP.NET worker process, and begin the debugging session.

To configure the remote debugger as a service, rerun Remote Debugger Configuration Wizard, and check the option to run it as a service.

Much like you did in this recipe, for the best debugging experience, you should configure the IIS application on the remote machine to run from a network share pointing to the web application's source folder on your development machine.

Once the web application is running in Visual Studio, select the Debug | Attach to Process menu option. The Qualifier drop-down menu is the name of the debugger instance you are connected to, and this should be the remote machine. If your target machine is not already listed, you can use the Find... button to locate the available debuggers.

Once you are connected to the correct machine, locate the ASP.NET worker process (w3wp) from the list, select Attach, and then close the window. You are now connected to the remote debugger for the web application, and can set breakpoints in your pages and step through code just as you would expect.

Deploying directly to a remote machine

The suggestion to run the programs on the remote machine via a file share is just a tip to make the development process simpler, and to eliminate the time it takes to redeploy the application you are trying to debug each time you make a change.

If you don't want to run the application from a file share, then you will need to deploy the application to the remote machine, and use the Attach to Process dialog to connect the debugging session each time.

Missing symbols

When debugging remote processes, you may find that after you attach to a process and set a breakpoint, it will look similar to the following screenshot:

Missing symbols

This message seen in the preceding screenshot appears because Visual Studio either can't load the symbol information (the PDB file) of the executable file, or the version that is running on the remote machine is not the same as the one on your development machine. For example, you may have recompiled the code on your development machine since you last deployed to the remote machine, causing the two environments to no longer match.

Fortunately, there is a way to fix this. Follow these steps:

  1. Navigate to the Debug | Windows | Modules menu entry to display the Modules window. (You have to be actively running the debugger for this option to be available.)
  2. The following screenshot shows a list of open modules, and whether or not a symbol file has been loaded for them. To load a symbol file, right-click on the entry from which you want to load them, and from the resulting menu, choose Load Symbols From | Symbol Path.
    Missing symbols
  3. From the file selection dialog box, locate the correct symbol file (PDB file) to load. Once you do this, the debug breakpoints will change to show filled-in red dots, as expected, and the Modules window will indicate that symbols are loaded.
..................Content has been hidden....................

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