Выбрать главу

After this lesson, you will be able to:

■ Identify important debugging tools for Windows Embedded CE.

■ Control debug messages through debug zones in drivers and applications.

■ Use the target control shell to identify memory issues.

Estimated lesson time: 90 minutes.

Debugging and Target Device Control

The primary tool to debug and control a Windows Embedded CE target device is by using Platform Builder on the development workstation, as illustrated in Figure 4-1. The Platform Builder integrated development environment (IDE) includes a variety of tools for this purpose, such as a system debugger, CE target control shell (CESH), and debug message (DbgMsg) feature, that you can use to step through code after reaching a breakpoint or to display information on memory, variables, and processes. Moreover, the Platform Builder IDE includes a collection of remote tools, such as Heap Walker, Process Viewer, and Kernel Tracker, to analyze the state of the target device at run time.

Figure 4-1 CE debugging and target control architecture

In order to communicate with the target device, Platform Builder relies on the Core Connectivity (CoreCon) infrastructure and debugging components deployed on the target device as part of the run-time image. The CoreCon infrastructure provides OS Access (OsAxS), target control, and DbgMsg services to Platform Builder on one side, and interfaces with the target device through the Kernel Independent Transport Layer (KITL) and the bootstrap service on the other side. On the target device itself, the debugging and target control architecture relies on KITL and the boot loader for communication purposes. If the run-time image includes debugging components, such as the kernel debugger stub (KdStub), hardware debugger stub (HdStub), and the OsAxS library, you can use Platform Builder to obtain kernel run-time information and perform just-in-time (JIT) debugging. Platform Builder also supports hardware- assisted debugging through Extended Debugging Interface (eXDI), so that you can debug target device routines prior to loading the kernel.

Kernel Debugger

The Kernel Debugger is the CE software-debugging engine to debug kernel components and CE applications. On the development workstation, you work directly in Platform Builder, such as to insert or remove breakpoints in the source code and run the application, yet you must include support for KITL and debugging libraries (KdStub and OsAxS) in the run-time image so that Platform Builder can capture debugging information and control the target device. Lesson 2, "Configuring the Run-Time Image to Enable Debugging," later in this chapter provides detailed information about system configurations for kernel debugging.

The following target-side components are essential for kernel debugging:

■ KdStub Captures exceptions and breakpoints, retrieves kernel information, and performs kernel operations.

■ OsAxS Retrieves information about the state of the operating system, such as information about memory allocations, active processes and threads, proxies, and loaded dynamic-link libraries (DLLs).

NOTE
Application debugging in Windows Embedded CE

By using the Kernel Debugger, you can control the entire run-time image as well as individual applications. However, KdStub is a kernel component that receives first-chance and second-chance exceptions, as explained in Chapter 3, "Performing System Programming." If you stop the Kernel Debugger during a session without stopping the target-side KdStub module first and an exception occurs, the run-time image stops responding until you reconnect the debugger, because the Kernel Debugger must handle the exception so that the target device can continue to run.

Debug Message Service

In Platform Builder, when you attach to a KITL-enabled and KdStub-enabled target device, you can examine debug information in the Output window of Microsoft Visual Studio 2005, which Platform Builder obtains from the target device by using the DbgMsg service in the CoreCon infrastructure. Debug messages provide detailed information about the running processes, signal potentially critical issues, such as invalid input, and give hints about the location of a defect in the code that you can then study further by setting a breakpoint and stepping through the code in Kernel Debugger. One of the kernel debugger stub's features is support for dynamic management of debug messages, so you can configure the debugging verbosity without source code modifications. Among other things, you can exclude Timestamps, Process IDs, or Thread IDs, if you display the Debug Message Options window that you can reach through the Target menu in Visual Studio. You can also send the debug output to a file for analysis in a separate tool. On the target device, all debug messages are sent directly to the default output stream handled through the NKDbgPrintf function.

NOTE
Debug messages with and without KITL

When both Kernel Debugger and KITL are enabled, the debug messages are displayed in the Output window of Visual Studio. If KITL is not available, the debug information is transferred from the target device to the development computer over a serial port configured and used by the OEM adaptation layer (OAL).

Macros for Debug Messages

To generate debug information, Windows Embedded CE provides several debugging macros that generally fall into two categories, debug macros and retail macros. Debug macros output information only if the code is compiled in the debug build configuration (environment variable WINCEDEBUG=debug), while retail macros generate information in both debug and retail build configurations (WINCEDEBUG=retail) unless you build the run-time image in ship configuration (WINCESHIP=1). In ship configuration, all debugging macros are disabled.

Table 4-1 summarizes the debugging macros that you can insert in your code to generate debug information.

Table 4-1 Windows Embedded CE macros to output debugging messages

Macro Description
DEBUGMSG Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug build configuration.
RETAILMSG Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug or release build configuration, yet not in ship build configuration.
ERRORMSG Conditionally prints additional printf-style debug information to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug or release build configuration, yet not in ship build con­figuration. This error information includes the name of the source code file and the line number, which can help to quickly locate the line of code that generated the message.
ASSERTMSG Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) and then breaks into the debugger, if the run-time image is compiled in debug configuration. In fact, ASSERTMSG calls DEBUGMSG followed by DBGCHK.
DEBUGLED Conditionally passes a WORD value to the WriteDebugLED function, if the run-time image is compiled in debug build configuration. This macro is useful on devices that provide only light-emitting diodes (LEDs) to indicate the system status and requires an implementation of the OEMWriteDebugLED function in the OAL.
RETAILLED Conditionally passes a WORD value to the WriteDebugLED function, if the run-time image is compiled in debug or release build configuration. This macro is useful on devices that provide only LEDs to indicate the system status and requires an implementation of the OEMWriteDebugLED function in the OAL.