Device Debugging and Emulation in Visual Studio 2005

 

Alex Feinman
OpenNETCF.org

November 2005

Applies to:
   Microsoft Visual Studio 2005
   Microsoft .NET Compact Framework version 2.0
Summary: Learn about how to use the Visual Studio 2005 Device Emulator and debugger for smart device projects—managed, native, and mixed. (19 printed pages).

Download Device_Debug_VS2005.msi from the Microsoft Download Center.

Contents

Overview of New Debugger Features in Visual Studio 2005
Device Emulator
Native Debugging: Attaching to Processes
Managed Debugging: Attaching to Processes
Managed Debugging: Debugging Interop Projects
Device Emulator Manager: ActiveSync Over DMA Transport Support
Conclusion
About the Author

Overview of New Debugger Features in Visual Studio 2005

Microsoft Visual Studio 2005 brings a host of new features in the device development area, bridging the gap that previously existed between tools in the Microsoft eMbedded Visual C++ development system and products in the Visual Studio development system. Previously, anyone who wanted to develop native device code had to install eMbedded Visual C++ and accept its dated user interface (UI), whereas developers who worked with managed device code enjoyed the newer, more advanced integrated development environment (IDE) of Microsoft Visual Studio .NET 2003. The real trouble started if a developer had a mixed device project, consisting of both managed and native code. The eMbedded Visual C++ and Visual Studio .NET 2003 systems even used different emulators. So, for example, a developer could not use remote tools shipped with eMbedded Visual C++ to inspect the emulator operating system that was running a managed application under the debugger.

Things would become really complicated if a user needed to create an unmanaged wrapper to allow using a COM object in a managed project. Debugging such a wrapper was even trickier.

In Visual Studio 2005, all device application development has been brought under the umbrella of a single IDE coupled with the latest pluggable compilers and an integrated debugger. Mixed solutions are supported. The debugger can attach to the running processes on the device or emulator, and the developer can select whether to debug managed or unmanaged code (although stepping from managed code to unmanaged code is not supported).

Device Emulator

Visual Studio 2005 introduces a new emulator called Device Emulator. Unlike the previous x86 based device emulators, the new one emulates an ARM device. The new emulator offers a very important advantage for Pocket PC and Smartphone development: you can install the same binaries to the emulator that you run on your device. While the executable files and libraries produced by the managed compiler are processor independent, this is not true for the native modules. The native modules are compiled for each processor type they need to support—MIPS, ARM, x86, and so on. Not unexpectedly, commercial applications are almost never available for x86 microprocessors—an architecture that the device emulators before Visual Studio 2005 used. For example, if you need to see how your application interoperates with a commercial Home screen plug-in, now you can do so on the emulator. Previously, this testing required an actual device.

With the latest software like Microsoft Windows Mobile version 5.0, obtaining a physical device may not be easy, but the emulator now gives you most of the real device features, including storage card simulation. In addition, the emulator supports a direct memory access (DMA) transport, which allows it to connect to Microsoft ActiveSync 4.0 as if it were a real device attached to the desktop computer.

To simulate a storage card

  1. In the emulator, on the File menu, click Configure.

  2. Select a folder in the file system of your computer that you want to make visible to the emulator as a storage card, and then click OK, as shown in the following figure. It's a good idea to pick a folder that does not have too many files. Remember, that various device applications that allow selecting a document, for example Pocket Word, use a DocList control, which scans the entire folder hierarchy of the storage card. If you share a root directory of one of your disks, the search will be rather time and resource consuming.

    After you configured the shared folder, start File Explorer in the emulator and notice that a Storage Card folder is now listed. The Storage Card folder is located under the root directory of the file system, so if you open the File Explorer for the very first time, you need to navigate one level up to see it. This folder provides a way to test Autorun features and other storage-card-related functionality without using the actual hardware, plus it provides an easy way to move the files between the device file system and the desktop computer that runs emulator. For example, debug output can be directed to a file, located in the Storage Card folder, and watched on the desktop computer.

Device Command Shell Tool

A tool called Device Command Shell, written by a Microsoft engineer Ori Amiga, is nearly indispensable for working with the emulator. When installed, Device Command Shell registers itself as a Visual Studio plug-in. It is unsupported, but so far has been periodically extended and kept up to date with changes in Visual Studio. The Device Command Shell simplifies managing and interacting with the device by making many common device-oriented tasks accessible from the Visual Studio 2005 Command Prompt window. These tasks include copying files between the desktop computer and the device, creating folders on the device, removing folders from the device, modifying the device registry, starting applications on the device, and so on. In the Visual Studio 2005 Command Prompt window, type CE and the autocomplete feature will show the list of supported commands. See the Device Command Shell documentation for more information about how to use this tool.

Native Debugging: Attaching to Processes

Visual Studio 2005 offers excellent support for native development and debugging. It is generally faster than eMbedded Visual C++ and offers the same rich debugger support for unmanaged projects that it offers for the desktop computer projects, including access to ARM disassembly. Visual Studio 2005 allows attaching to a running process and detaching from one without terminating it.

Debugging the Today Screen Plug-in on Pocket PC

As a demonstration of the unmanaged native debugger, this article will step you through a screen-painting routine of the sample Today screen plug-in, which is provided as a part of the Pocket PC 2003 SDK. For the purposes of this article, the sample has been converted to work with Visual Studio 2005. The Visual Studio 2005–compatible solution is provided as a download sample for this article.

To prepare the solution for debugging

  1. Build and deploy the solution using the Debug configuration. To deploy the solution, click Build, and then click Deploy.

  2. Register the Today screen item by using CeRegEdit by doing the following steps:

    • Click Start, point to All Programs, point to Microsoft Visual Studio 2005, point to Visual Studio Remote Tools, and then click Remote Registry Editor.

    • When prompted to select a device, choose the one you are using as a deployment target in the project that you are debugging, and then click OK.

      At this point you should see the registry contents of the target device (emulator), as shown in the following figure.

    • Expand the device (emulator) registry subtree by clicking the plus sign (+) next to it, and then browse to HKEY_LOCAL_MACHINE\Software\Microsoft\Today\Items.

    • Right-click Items, point to New, and then click Key. When prompted, type Sample as the key name. Click OK to create the new key.

    • Right-click in the right panel, point to New, and then click String Value. Type DLL as the name, and type \Program Files\TodayPlugin\TodayPlugin.dll as the value. Click OK to save the new value.

    • Right-click in the right panel, point to New, and then click DWORD Value. Type Flags as the name, and type 4 as the value. Click OK to save the new value.

    • Right-click in the right panel, point to New, and then click DWORD Value. Type Type as the name, and type 4 as the value. Click OK to save the new value.

      When you are finished, the registry editor should look like the following figure.

  3. On the emulator, click Start, click Settings, and then click Today, as shown in the following figures.

  4. On the Items tab, select Sample, as shown in the following figure.

  5. Close the Settings screen by clicking OK.

  6. On the Today screen, ensure that you can see the new sample Today screen item, as shown in the following figure.

  7. On the Debug menu in Visual Studio, and then click Attach to Process.

  8. In the Attach to Process dialog box, under the Transport list select Smart Device.

  9. Next to the Qualifier list, click Browse.

  10. In the Connect to Device dialog box, under Devices, select the appropriate emulator (or device if the emulator is cradled) from the list, and then click Connect, as shown in the following figure.

    To debug a Today screen plug-in, you need to attach to the process called mstli.exe. All Today screen items run in the context of the mstli.exe process.

  11. In the list of processes that has appeared under Available Processes, select mstl.exe, and then click Attach, as shown in the following figure.

    The final step is to ensure that the symbols are loaded.

  12. On the Debug menu, point to Windows, and then click Modules.

  13. Find the TodayPlugin.dll in the list of loaded modules, as shown in the following figure.

    Notice that next to the TodayPlugin.dll, it says No symbols loaded.

  14. Right-click the module, and then select Load Symbols.

  15. Browse to the project output directory (Pocket PC 2003 (ARMV4)\Debug).

    Visual Studio will load the symbol information and marks the module appropriately.

  16. Now you can set a break point in the plug-in's code and see it being hit.

Managed Debugging: Attaching to Processes

You can attach a debugger to a running managed application. Note that the following steps apply to both a real device and an emulator.

To attach a debugger in Visual Studio 2005

  1. Open a managed smart device project.

  2. Press CTRL+F5 to start the application.

  3. On the Debug menu, click Attach to Process.

  4. In the Attach To Process dialog box, click the Transport list, and then select Smart Device as a transport, as shown in the following figure.

  5. Click Browse to browse for your target device. The Connect to Device dialog box opens, as shown in the following figure.

  6. In the Connect to Device dialog box, select the appropriate device, and then click Connect.

  7. In the Attach to Process dialog box, select from the list of Available Processes the process that you want to debug, and then click Attach.

    Note By default, attaching to a managed process is disabled on the device side. If you try to attach to a managed process, you will get an error message that describes the problem, as shown in the following figure.

    To enable attaching to a managed process, you need to modify the device registry. You can modify the device registry by using either the Device Command Shell or CeRegEdit tool.

    Device Command Shell

    • CE Open <device number>

    • CE NETCFAttach Enable

      CeRegEdit tool

      Use the CeRegEdit tool as described in this article's previous Debugging the Today Screen Plug-In on Pocket PC section to set the following registry value:

      [HKLM\Software\.NetCompactFramework\Managed Debugger] 
      AttachEnabled=1
      

Managed Debugging: Debugging Interop Projects

One of the more complex debugging scenarios that you may encounter when writing managed code for smart devices is trying to catch an error inside a so-called interop call—a call from the managed code into a native module. In Visual Studio 2005, you can catch an error this way relatively effortlessly.

To debug interop projects

  1. In Visual Studio 2005, create a new C# Pocket PC 2003 device application project, and then add a menu command called Test.
  2. Add a new project to the solution by following these steps:
    • On the File menu, point to New, and then click Project. The New Project dialog box opens.

    • Select C++, select Smart Device Project, and then select Win32 SmartDevice Project.

    • In the Solution box, select Add to Solution.

    • Type InteropDLL as the name of the project, and then click OK to start the Win32 Smart Device Project Wizard.

    • On the Welcome page of the wizard, click the Application Settings link located on the left side of the wizard page. This link opens the Project Settings page.

    • On the Project Settings page, select DLL as the Application type, and then select the Exports Symbols check box under Additional options.

    • Click Finish.

    • In Solution Explorer, right-click the InteropDLL project, click Add, and then click New Item.

    • On the Add New Item dialog box, select Code under Categories, and then select Module Definition File under Templates.

    • Type InteropDLL.def as the name of the module definition file, and then click Add.

    • Add the following two lines to the InteropDLL.def file after the line containing LIBRARY ."InteropDLL".

      EXPORTS
      fnInteropDLL
      
    • Modify the InteropDLL.h file by changing the following code:

      INTEROPDLL_API int fnInteropDLL(void);
      

      to:

      extern "C" INTEROPDLL_API int fnInteropDLL(void);
      

      This step avoids C++ name "mangling." If this step is not completed, the function will be exported with extra symbols appended to the name (for example, ?fnInteropDLL@@YAHXZ), and the marshalling code will not be able to find the function at run time and will throw a MissingMethodException.

    • Build the DLL project.

    • In Solution Explorer, right-click the C# device project, and then click Add Existing Item. In the File Type list, select Executable Files (*.exe,*.dll,*.ocx).

    • Select the InteropDLL.dll file you just built. You need to go up one folder level, and the DLL file will be in the InteropDLL\Pocket PC 2003 (ARMV4)\Debug folder. Instead of clicking Add, click the arrow next to the Add button, and select Add As Link. This step ensures that your project will pick up the most recent version of the DLL.

    • In the device project tree, right-click InteropDLL.dll, and then click Properties.

    • In Properties, select Copy Always for the Copy to Output Directory property, and then ensure that Build Action property is set to Content.

    • In the Form1 class of the device project, add the following Interop definition.

         [DllImport("InteropDLL")]
         extern static int fnInteropDLL();
      
    • Open the form designer for the Form1 class of the device project, and then double-click the Test command that you created in step 1.

    • Add the following line to the generated event handler.

      private void menuItem1_Click(object sender, EventArgs e)
      {
         MessageBox.Show(fnInteropDLL().ToString());
      }
      

      For Visual Studio to be able to load the symbols for your unmanaged DLL, you need to add a path to the symbol file.

    • On the Tools menu, click Options.

    • In the Options dialog box, expand Debugging, and then click Symbols.

    • Under Symbol file (.pdb) locations, add a new location—the Debug directory of your DLL project.

    • Set a breakpoint in the InteropDLL.cpp file inside the fnInteropDLL function, on the line that says return 42.

    • Start the managed form project without debugging (CTRL+F5).

    • After you verify that the form application is running in the emulator, click Debug on the Visual Studio 2005 menu, and then click Attach to process.

    • In the Attach to Process dialog box, select Smart device in the Transport list, and then select the emulator name in the Qualifier list.

    • In the list of available processes, select the device project executable file.

      Note You cannot step from the managed code into unmanaged code. You can have only one debugger at a time attached to your process.

    • Ensure that Native (Smart Device) code appears in the Attach To box. If it is not there, click the Select button, and, in the Select Code Type dialog box, select Debug These Code Types and then select **Native (Smart Device)**¸as shown in the following figure. In the Select Code Type dialog box, click OK to return to the Attach to Process dialog box, as shown in the following figure

    • Click Attach.

    • In the application's form, click the Test command.

      The breakpoint should be hit at this point.

Device Emulator Manager: ActiveSync Over DMA Transport Support

Device Emulator Manager is a new tool that you can use to conveniently manage numerous device emulator instances from a single location. It is available on the Visual Studio 2005 Tools menu. When started, the Device Emulator Manager displays all of the device emulators registered with the system. When you install a new SDK, such as Windows Mobile 5.0 SDK, a set of new device emulators appears in the list.

Figure 1 shows Device Emulator Manager.

Figure 1. Device Emulator Manager

To manually start an instance of Device Emulator

  • In Device Emulator Manager, right-click the desired emulator platform from the list, and then click Connect.

    The emulator starts. When a circle with an arrow inside it appears next to the emulator description line, the emulator is active and connected.

To connect an instance of the emulator to ActiveSync

  1. Make sure that the DMA transport is enabled in the ActiveSync connection settings. To do this, right-click the ActiveSync icon in the taskbar notification area, and then select Connection Settings, as shown in the following figure.

    The Connection Settings dialog box opens, as shown in the following figure. Verify that Allow connections to one of the following is selected.

  2. In Device Emulator Manager, right-click the emulator entry, and then click Cradle.

    You should see an ActiveSync connection being established. The emulator will be marked as cradled as shown in the following figure.

Note If you are not familiar with the installation and usage of ActiveSync, visit the ActiveSync FAQs for general information about working with ActiveSync,

Using a Cradled Emulator with Remote Device Tools

An interesting consequence of being able to connect the emulator to ActiveSync is that now you can use remote tools such as Remote Registry Editor with the emulator, by simply selecting the device as the tool connection target rather than targeting the emulator. When starting any of the remote tools and the Select Device dialog box appears, you can pick the Pocket PC Device option—as if a real device has been connected.

In fact, you can use any Remote API (RAPI)–based tool with the emulator, including CECopy, RapiConfig, and other tools from the SDK and Windows Mobile Developer Power Toys. When using RAPI tools with the new emulator, always cradle the emulator using the Device Emulator manager and select Pocket PC or Smartphone Device as the tool's target because the new emulator is not directly accessible from the old tools.

Conclusion

The Visual Studio 2005 debugger is an extremely powerful tool that enables stepping through both managed and unmanaged applications, while displaying memory contents, during disassembly, and evaluating expressions.

Device Emulator enables a software developer to prototype, develop, and debug applications quickly. It provides an experience that is very close to a real device.

About the Author

Alex Feinman is a Software Engineer at Corrigo Incorporated, a Northern California technology company and a Microsoft Certified Solution Provider. Alex is also a member of OpenNETCF.org Advisory Board.