WinCE 编程实验(第十五章 Windows CE侦错环境)

 

 

第十五章  Windows CE侦错环境

 

Windows CE提供了强大的原始码的侦错工具,它被整合在从系统开发到应用软件开发的多个工具中。Windows CE将侦错分为多个级别:在目标程序与Windows CE原始程序代码中内嵌的侦错用程序代码;用Emulator支持软件仿真方式的主机-目标装置的联机侦错;真实目标硬件上的主机-目标装置联机侦错等。

 

本章主要从使用者的角度介绍Windows CE的侦错器,考虑到篇幅与实用目标,对于Windows CE中的侦错机制不作详述。

 

15.1 简介

 

Windows CE的整合开发环境(IDE)具有多种工具,允许使用者彻底地测试并侦错一个平台。下面先简要介绍IDE中的各种测试和侦错工具:

 

平台及应用程序的侦错  核心侦错器控制一个操作系统映像的行为,由此映像的性能来为使用者提供讯息:使用者可以利用核心侦错器将配置装置连接所需的所有功能整合起来,并将映像下载到一个目标装置上,从而监控并侦错一个操作系统映像。这个整合使核心侦错器能够控制一个操作系统映像的行为,并由该映像的性能来为使用者提供讯息。新的侦错窗口和IDE中的选单选项提供了对所有处理程序、执行绪的查询,以及其它的目标侦错讯息。可以使用核心侦错器来侦错Windows CE核心中的应用程序代码,如果平台设置build setting时选择了enable kernel debugging,核心侦错器就会自动启动。应用程序侦错器与核心侦错器不同,它仅仅控制一个运行在已下载的操作系统映像上的一个应用程序。当这个应用程序运行在一个操作系统映像(此映像同时运行在一个目标装置上)上时,可以对它进行侦错。

 

扩展的侦错接口  扩展的侦错接口允许终端使用者通过使用一个第三方的装置磁盘驱动器及一个硬件探测器或仿真器,来控制并侦错一个目标装置。

 

仿真器  仿真器是一个仿真支持Windows CE平台的硬件行为的工具。通过仿真器,使用者可以设计和建立一个基于Windows CE的平台,并利用仿真硬件的软件来测试它,而不是测试在硬件之上的平台。同时,仿真器也允许使用者为应用程序开发者提供一个虚拟硬件平台,开发者可通过它测试此平台上的应用程序。

 

远程工具  远程工具允许使用者在开发工作站中,来远程执行一系列的程序设计任务。在建立远程工具和平台管理器之上的目标机器之间的连接后,可以完成诸如下载一个档案到目标机器上、监控目标装置之上的处理程序和执行绪的状态、测试目标装置的性能等任务。一次只能运行一个远程工具,但是许多远程工具可以显示多个窗口。如果连接到一个目标装置上,则工具栏上的按钮和远程工具窗口中的一些选单项就会处于活跃状态。

 

远程程序的开发  一个远程程序是一个分散开的应用程序,一部分位于目标装置上,一部分位于开发工作站上。远程程序的各部分之间通过平台管理器互相沟通。通过使用平台管理器应用程序接口API,可以开发一个远程程序来平衡已经存在的平台管理器的功能。

 

平台管理器  平台管理器是操纵基于Windows CE平台的开发工作站间通讯的一种技术。平台管理器允许开发工具下载并连接到独立于媒体的目标装置上。它支持处于两个不连续层之间的开发工作站和目标装置之间的连接。在某一层上,平台管理器支持开发工作站的应用程序和目标装置之间的连接,也就是应用程序连接;在另一层上,平台管理器支持Platform Builder中的核心层上的连接,也就是核心层连接。

 

15.2 侦错工具

 

Windows CE操作系统提供了一个逐步操作的指南,来建立、侦错运行时的操作系统映像和运行在仿真器上的简单应用程序。下面先介绍一下侦错中常用工具。

 

在建立操作系统映像并连接到Emulator/CEPC之后,点击图标(或者选择选单Target下的Download/Initialize项),下载操作系统映像,在下载的过程中,IDE中会有一个对话框显示下载过程中的讯息,下载后屏幕中央会出现一个新的工具栏,如图15.1所示。

 

15.1 工具栏

 

下面逐个介绍各个按键的作用:

 即Debug选单下的Go选项,选择此项开始核心侦错。

 即Debug选单下的Stop Debugging选项,选择此项停止核心侦错。

 即Debug选单下的Break选项,选择此项停止程序的执行,进入侦错状态。

 即Debug选单下的Show Next Statement选项,选择此项显示指令指针的原始程序代码。

 即Debug选单下的Step IntoStep OverStep OutRun to Cursor选项,作用分别为执行下一条语句、跳过下一条语句、从目前的函数中跳出、执行程序到光标所在的程序代码行。

Debug选单下的Quick Watch选项,当侦错一个工程且处于break状态时,此选项才可用,点击后会弹出一个对话框,在此对话框中可以检测一个变量或表达式的值、修改一个变量的值、或将一个变数加到Watch Window中。值得注意的是Current Value表项中一次只能显示一个变量或表达式,如果在Expression中输入新的变量或表达式后按ENTER键,原先在Current Value中的值就会被覆盖。各个输入项及按钮说明如下:

 

Expression中输入变量或表达式的值。

Name中显示在Expression中输入或选择的变量名或表达式。

Value中显示在Expression中输入或选择的变量或表达式的值。

Recalculate按钮:计算在Expression中的表达式的值并显示在Current Value框中。

Add Watch按钮:将变量或表达式加入到Watch Window中,如果Watch Window没有被显示,同时将其显示。

Close按钮:关闭对话框,并不做任何更动。

 弹出或隐藏Watch Window(详细请见如下介绍)。

 弹出或隐藏Variables Window(详细请见如下介绍)。

 弹出或隐藏Registers Window(详细请见如下介绍)。

 都是弹出或隐藏Memory Window(详细请见如下介绍)。

 弹出或隐藏Call Stack(堆栈呼叫) 窗口(详细请见如下介绍)。

 弹出或隐藏Disassembly Window(反组译窗口),反编译即在侦错期间将机器语言翻译成助记符号的编译过程。此窗口可侦错最佳化的程序代码,或追踪包含多条语句的原始码,它将每一行的程序代码都看作一个整体。比如下面程序代码行包含多条指令:

 

x = 1y = 7z = 3

 

在此原始码下,不能从一条原始码跳到下一条,也不能在除了第一条语句的其它地方设置中断点。

 

反编译窗口操作的是反编译指令(编译语言或字节码)而不是原始码语句。透过使用此窗口,可以在任何指令处设置断点,如果在此窗口中使用了Step IntoStep Over指令,则侦错器会一条指令一条指令的执行程序,而不是一行、一行的执行。当侦错最佳化程序代码时,透过反编译指令观察和追踪程序代码将非常有用!

 

 弹出或隐藏List Nearest Symbol Window

 弹出或隐藏Advanced Memory Window(详细请见如下介绍)。

 弹出或隐藏Processes Window(详细请见如下介绍)。

 弹出或隐藏Threads Window(详细请见如下介绍)。

 弹出或隐藏Modules and Symbols Window(详细请见如下介绍)。

 

侦错过程中可以应用许多对话框来追踪变量的值、处理程序执行绪的执行情况等。下面将逐一进行介绍:

 

15.2.1 Watch Window

 

Watch Window窗口如图15.2所示。

点击 按钮之后会出现此窗口,使用此观察窗口可以指定希望在侦错程序的过程中所希望观察的变量和表达式,也可以修改观察窗口中变量的值。此窗口中下有四个标签:Watch 1Watch 2Watch 3Watch 4。每一个卷标都能以表格形式显示一个使用者所确定的变量和表达式的值。可以将所希望同时观察到的变量放在一个卷标中。例如,可以将和一个特定窗口有关的变量放在一个卷标中,而将和一个对话框相关的变量放在另一个窗口中。当侦错此窗口时可以使用第一个标签,而侦错此对话框时使用第二个标签。当将一个数组或是对象、结构变量放在观察窗口中时,“+”或者“ -”逻辑栏会显示在Name栏中,可以使用这些逻辑栏来扩展或收缩对变量的观察。如果一个变量变成了红色,这表明此变量刚刚被改变过。

 

15.2 Watch Window

 

15.2.2 Variables Window

 

Variables Window如图15.3所示。

 

15.3 Variables Window

 

变量显示窗口提供了对程序目前上下文很重要的变量的快速查询。他有三个标签:

Auto:显示目前语句和前一条语句的变量讯息。变量按字母循序显示,如果一条语句跨越了多行,则此卷标显示和此语句相关的行变量,但是有最多10行的限制。

Locals:显示区域变量的变量名、值和类型。当追踪一个程序时,新的变量会进入到目前区域中。

this:显示由this指针所指向的对象的类型、名称和值。所有此对象的基类都会被自动扩展。

 

每一个卷标都包含一个表格,有变量名和变量的值。侦错器自动地填满这些区域。如果一个值显示成红色,表示这个值刚刚被改过。只有最后被改过的值为红色。在侦错的过程中可以修改Value栏中的变量的值(双击Value域中的值),但是不能增加变量或表达式到Variables Window中,只能使用Watch Window。通过使用“+”和“-”,可以扩展数组、结构类型的变量。

 

15.2.3 Memory Window

 

Memory Window如图15.4所示。

 

15.4 Memory Window

 

内存窗口显示了给定地址的内存中数据的一个快速浏览,透过点击Memory Window可以在某一行中间设置一个插入点,则Memory Window每次显示变量的上下文时都会从这一行开始。也可以从Editor Window中选择一个变量名或是表达式拖到Memory Window中,则这个变量就会被显示,从此项目被放置的行开始。

 

Address:框中显示内存中一个可查询的数据的储存地址。在此窗口中点击右键,会出现一个快捷菜单,有如下选项:

 

Byte Format:用字节形式显示内存讯息,例如:00 0A FE 32

Short Hex Format:用短的十六进制形式显示内存讯息,例如: 000A FE32

Long Hex Format:用长的十六进制形式显示内存讯息,例如: 000A FE32

Toolbar:显示address工具栏。

Hide:隐藏此窗口。

 

15.2.4 Registers Window

 

Registers Window如图15.5所示。

 

15.5 Registers Window

 

此窗口显示核心CPU缓存器。每一个CPU都有一组专用的缓存器。除了一些标记之外,可以对任何缓存器的值进行修改(在Watch Window中),只有十六进制数才是有效的。在此窗口中点击右键,会出现一个快捷菜单,有如下选项:

Floating Point Registers:显示核心的浮点缓存器。

Hide:隐藏此窗口。

 

15.2.5 Call Stack Window

 

Call Stack Window如图15.6所示。

 

15.6 Call Stack Window

 

在侦错过程中,此窗口显示目前函数呼叫的call stack。当一个函数被呼叫时,它被压在堆栈顶。当函数回传时,它从堆栈顶放出。Call Stack Window显示了堆栈顶被执行的函数,下一行显示的是原先的函数。精简模式下,此窗口还显示每一个被呼叫函数的参数类型和参数值。双击窗口中的函数可以观察函数的原始码或反编译程序代码。如果所选择的函数的原始码不可现,则函数的目标程序代码显示在反编译窗口中。追踪函数的程序代码会改变Variables Window和其它侦错窗口中的函数讯息,但是并不修改要执行的下一条语句,也不修改储存在程序计数器中的值。

Process:显示和呼叫堆栈有关的处理程序。通过选择下拉选单,可以观察不同的处理程序。如果选择目前处理程序,则目前处理程序和目前执行绪的呼叫堆栈会被显示(目前处理程序是指当侦错器停下来,或是遇到了一个断点时活跃的处理程序,即用新讯息刷新窗口的处理程序)

Thread:显示呼叫堆栈的目前执行绪。通过选择下拉选单,可以观察不同的执行绪。在此窗口中点击右键,会出现一个快捷选单,有如下选项:

 

  Refresh:删除窗口中的所有入口,只留下目前的入口。

   Log:将此窗口中的数据格式化并复制到Output Window中的Log标签栏中。

  Auto Log on Step:在每一步侦错后,自动将此窗口中的数据格式化并复制到Output Window中的Log标签栏中。

Go To Code:打开选中函数的程序代码窗口。

   Insert/Remove Breakpoint:在反编译窗口中,在光标所在的那一行设置一个断点,如果此行已经有一个断点了,则此断点被去除。

 Enable Breakpoint:让一个原先不活跃的断点活跃。

  Run to Cursor:执行到光标所在处并暂停。

Parameter Values:显示Call Stack Window中函数的参数值。

Parameter Types:显示Call Stack Window中函数的参数的类型。

Hexadecimal Display:将选中的值变成十六进制。

Hide:隐藏此窗口。

 

15.2.6 A dvanced Memory Window

 

Advanced Memory Window如图15.7所示。

 

15.7 Advanced Memory Window

 

此窗口让你可以定位、重新定位、或将数据放到内存中。

1. Search标签栏:在内存搜索data域中的任何数据

Start Address:输入所想开始搜索的十六进制地址或变量名。

Rangein bytes:输入从Start Address开始搜索的用十进制表示的字节数。

Data:输入由Start AddressRange所限制的想要搜索的数据,Data必须是所选择的Type类型。

Type:选择如下类型:bytewordlongfloatdoublechar*wchar_t*

OK:开始搜索。

Stop Search:停止搜索。

 

2. Move标签栏:将一块内存的数值从开始地址移动到目标地址

 

 

l          Start Address:以十六进制形式输入转移的开始地址。

l          Rangein bytes):从Start Address开始想要转移的字节数。

l          Destination:以十六进制形式输入转移的目标地址。

l          OK:开始转移。

l          Stop Move:停止转移。

3. Fill标签栏:用所给数值填充一块内存

 

 

l          Start Address:以十六进制形式输入想要填充的开始地址。

l          Range:输入从Start Address开始想要填充的字节数。

l          Data:想要在由Start AddressRange确定的位置中填充的数值,必须是选择的类型。

l          Type:选择如下类型:bytewordlongfloatdoublechar*wchar_t*

l          OK:开始填充。

l          Stop Fill:停止填充。

 

15.2.7 P rocesses Window

 

Processes Window如图15.8所示。

 

15.8 Processes Window

 

程序窗口显示了执行在目标设备上的所有程序的讯息,当侦错器执行时、侦错器停止或遇到断点时,此窗口所显示的讯息是不同的。

1. 当侦错器正在执行时,窗口显示如下讯息

l          Process Name:程序的名字。

l          Process address:显示目标设备的全域虚拟地址空间里程序的起始地址。

l          Access Key:显示执行绪所需的存取程序地址空间的存取键,直接与程序的入口索引相对应。

l          Process Handle:显示程序的控制代码。

l          CurZoneMask:显示为这个程序所设置的有效的侦错分区。侦错分区允许通过使控制侦错讯息输出的宏启动来进行侦错。

2. 当侦错停止时,窗口显示如下讯息

l          Name:程序的名字。

l          VMBase:程序在内存中的部分的起始地址,如果没在使用则为0

l          AccessKey:显示目标设备的全域虚拟地址空间里程序的起始地址。

l          TrustLevel:程序的等级。

l          hprocess:程序的控制代码。

l          BasePtr:程序装载的基础指针。

l          TlsUseL32b:显示前32个插槽中在使用的TLS的屏蔽位。

l          TlsUseH32b:显示后32个插槽中在使用的TLS的屏蔽位。

l          CurZoneMask:显示为这个程序所设置的有效的侦错分区。侦错分区允许通过使控制侦错讯息输出的宏启动来进行侦错。

l          pProcess:程序的指针。

l          CmdLine 指向程序开始的命令列的指标。

 

15.2.8 Threads Window

 

Threads Window如图15.9所示。

 

15.9 Threads Window

 

此窗口显示一个程序中的执行绪或执行的路径。当侦错器执行时、侦错器停止或遇到断点时,此窗口所显示的讯息是不同的。

1. 当侦错器正在执行时,窗口显示如下讯息

l          hThread:显示执行绪的控制代码。

l          Thread State:显示执行绪的如下的一种状态:

n          Running:执行绪正在执行。

n          Runnable:执行绪可以执行。

n          Blockd:执行绪被堵塞。

n          Suspnd:执行绪被暂停。

n          Sleepg:执行绪在睡眠。

n          Sl/Blk:执行绪被暂停且在睡眠。

 

l          Access Key:显示目前执行绪的存取键,对正在执行的执行绪此域无效。

l          hCurProc:显示创造此执行绪的程序的控制代码。

l          CurPrio:显示执行绪目前的优先权,此优先权也是程序正在执行的优先权。

l          BasePrio:显示执行绪的基础优先权,也是没有倒置发生时程序的优先权。

l          KernelTime:执行绪在核心模式下所消耗的C P U时间。

l          UserTime:执行绪在使用者模式下所消耗的C P U时间。

2. 当侦错停止时,窗口显示如下讯息:

l          hThread:执行绪的控制代码。

l          pThread:执行绪的指标。

l          RunState:执行绪的状态,与侦错器执行时的ThreadState相似:DyingDeadBuriedSlpgsleeping)、Awakawake)、Rungrunning)、Runab(abletorun)RunBlkd (able to run, but blocked)RunNeeds (needs to run)

l          InfoStatus:显示执行绪的状态讯息。

l          Umode:使用者模式。

l          Kmode:核心模式。

l          StkFlt:有堆栈错误。

l          UsrBlkd:被使用者调用所堵塞。

l          WaitState:等待循环的状态,可以有SignaledProcessingBlocked

l          AccessKey:显示目前执行绪的存取键,对正在执行的执行绪此域无效。

l          HCurProcIn:显示创造此执行绪的程序的控制代码。

l          HOwnerProc:显示拥有此执行绪的程序的控制代码。

l          CurPrio:显示执行绪目前的优先权,此优先权也是程序正在执行的优先权。

l          BasePrio:显示执行绪的预设优先权,也是没有倒置发生时程序的优先权。

l          KernelTime:执行绪在核心模式下所消耗的CPU时间。

l          UserTime:执行绪在使用者模式下所消耗的CPU时间。

l          Quantum:此执行绪的时间量。

l          Quantuleft:此执行绪剩下的时间量。

l          SleepCount:此执行绪的睡眠计时。

l          SuspendCount:此执行绪的暂停计时。

l          TlsPtrTLS指标。

l          LastError:此执行绪的最后一个错误,由SetLastError所设定,用GetLastError得到。

l          StackBase:堆栈的起始地址。

l          StkLowBnd :堆栈起始地址的最低范围。

l          CreatTimeH :显示执行绪创造时间的高64位。

l          CreatTimeL:显示执行绪创造时间的低64位。

 

15.2.9 Modules and Symbols Window

 

Modules and Symbols Window如图15.10所示。

 

15.10 Modules and Symbols Window

 

此窗口可以对一个特定的模块安装或移除SymbolSymbol可是代表一个缓存器的名字、一个绝对的值,或者一个内存地址(相对的或绝对的)。Symbol是由编译器产生的,并解释原始码和目标码之间的关系。如果对Symbol做了修改,可以移除Symbol,做修改,然后用执行档再安装Symbol。当侦错器执行时,和侦错器停止或遇到断点时,此窗口所显示的讯息是不同的。

1. 当侦错器正在执行时,窗口显示如下讯息

l          Module:显示所有执行在目标设备上的模块的名称。

l          Image Address Range:模块所在的目标设备的内存的地址范围。

l          Relocated Data Address Range:重新分配的数值的地址范围。

l          Status :有如下两种模块的侦错symbol的状态:

l          Loaded:侦错器已经安装了侦错symbol

l          Unloaded:侦错器还没有安装侦错symbol

l          Path:在平台式计算机中储存的模块的路径。

l          PDB Path:在连接时候产生的侦错讯息储存的路径。

2. 当目标控制(C E S H)正在执行,侦错器停止时,窗口中显示如下讯息

l          Module:目前执行在目标设备上的模块的名字。

l          Address:显示模块被下载的目标设备的下载地址。

l          Module/Process Handle:模块/程序的控制代码。

l          InUSE:显示模块的使用状况。执行檔(.exe)会显示为NotAvailable

 

15.3 侦错过程

 

在下载了操作系统映像并加载了操作系统之后,就可以侦错操作系统了。在侦错过程中,将使用核心侦错器来侦错使用者端的操作系统。精简模式下,核心侦错器是启动的。Platform Builder在操作系统加载时会自动启动核心侦错器,并在IDE窗口中显示侦错工具列。要侦错平台,首先必须暂停操作系统的执行。当操作系统正在执行时,不能设置断点。简单介绍侦错过程如下:

1.          Debug选单中选择Break,或点选。

2.          打开欲侦错的与设备有关的程序代码所在的文件,并找到需要的程序代码行。

3.          将光标放在此程序代码行,按F9键,或用鼠标点选,左边红色圆点表明已经在此处设置了一个断点。

4.          Debug选单中选择Go或用鼠标点选,程序开始执行,当执行到断点处时会停住,可以看见一个黄色的箭头在断点处。

5.          此时就可以利用前面所介绍的各种工具来对平台进行侦错了,包括单步追踪、观察变量等多种侦错功能。

6.  Edit选单中选择Breakpoints选项,选择RemoveAll按钮,点选OK,可去掉

设置的所有断点。

7.  Debug菜单中选择Go选项。

到目前为止已经成功地中断了操作系统,设置并启动了一个设备上的断点,然后去掉了此断点。如果要停止侦错操作系统,执行接下来的步骤。

8.      Debug菜单中选择Stop Debugging,或者点击 图示,将控制权还给IDE

9.      Target菜单中选择Disconnect或者点击 图示,再点击OK,中断连结。侦错过程结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值