目录

第1章调试说明    1

1.1 调试设置    1

1.2 跟踪代码    2

1.3 断点    2

第2章模块生命周期    4

2.1 exe模块    4

2.2 dll模块    5

第3章调试WinCE程序    7

3.1 部署附加文件    7

3.2 共享文件夹    8

第1章调试说明

1.1 调试设置

使用Visual C++ 6.0打开一个项目,然后按下F5键即可开始调试程序。其实质就是启动VC++调试器,加载exe文件。具体加载哪个exe文件呢?请参考下面的项目设置界面

图1.1 VC++6.0调试设置

调试器加载的执行程序就是"Executable for debug session"指定的exe文件。对于exe项目而言,VC++会自动进行设置。对于dll项目而言,需要人工设置。

"Working directory":调试器加载exe之前,会设置当前目录为该目录。如果该项为空,则设置当前目录为dsp所在目录。上图中,Working directory为C:\,所以代码里GetCurrentDirectory获得的当前目录将是C:\。代码fopen("File.txt","wb")) 创建的文件File.txt也将在C:\下。

"Program arguments":调试器将给exe传递命令行参数,也就是说将把这里的字符串传给 main(int argc,char *argv[]) 函数的argv。

一个exe项目和一个dll项目里,按下F5键后,调试器所做的工作并没有本质的区别——都是加载指定的 exe 文件。

1.2 跟踪代码

调试程序的时候,调试器会根据程序的执行进度自动跳到对应的代码行。为什么会这么神奇?因为编译器做了两个工作:

1、执行程序用到的源文件(*.c、*.cpp)被保存至pdb文件里;

2、编译的时候,调试信息被写到了exe或dll文件里。

因为有了pdb文件,调试器能够将断点定位到源文件。又因为有了调试信息,调试器能够将断点精确到行。

也就是说:调试程序的时候要跟踪代码就必须保证pdb文件存在,并且是最新的。

使用UltraEdit打开一个VC++6.0 Debug版的exe或dll文件。在文件末尾可以看到pdb文件的全路径。这就意味着pdb文件一旦生成就不要轻易移动,否则调试器将无法跟踪代码。非要移动pdb文件的话就一定要将它和exe或dll文件放在同一文件夹下。

图1.2 pdb文件目录

1.3 断点

VC++6.0、EVC++3.0/4.0的断点信息是保存在opt文件里的;VC++7.0及其以后版本的断点信息是保存在suo文件里的。当按下F5键开始调试的时候,调试器将加载这些断点信息,一旦代码执行到断点所在代码行的时候,调试器将暂停程序的执行。

第2章模块生命周期

模块就是exe或dll文件。当用户使用鼠标双击一个exe文件图标,要运行这个程序的时候,模块就具有了"生命"。本章将讨论一个模块在其生命周期内的关键事件点。理解这些对于调试程序将会有一定的帮助。

2.1 exe模块

exe模块的生命周期为:

1、静态初始化全局变量,包括静态和动态;

2、调用 main 或 WinMain;

3、初始化静态变量;

4、从 main 或 WinMain 返回;

5、销毁静态变量;

6、销毁全局变量。

举例说明:

DWORD g_dwTickCount = GetTickCount();

DWORD g_dwTemp = g_dwTickCount;

int&GetStaticInt()

{

static int i = 0;

return i;

}

int main()

{

GetStaticInt();

}

执行步骤如下:

1、初始化全局变量

首先是静态初始化,即将g_dwTickCount 和 g_dwTemp全部初始化为零;

接着是动态初始化。调用GetTickCount函数,并g_dwTickCount赋值。

g_dwTemp = g_dwTickCount是一个危险的语句——假如g_dwTickCount、g_dwTemp在不同的cpp文件里,则这两个全局变量的初始化顺序是无法预知的。如果g_dwTickCount先完成初始化g_dwTemp将得到预期的值,反之如果g_dwTemp先初始化则它始终为零。

2、程序进入main函数

3、初始化静态变量

GetStaticInt里有静态变量i。第一次调用GetStaticInt时,该静态变量被创建。

4、从main函数返回

5、销毁静态变量

这个程序里,就是销毁GetStaticInt函数里的静态变量i。

6、销毁全局变量

即销毁全局变量g_dwTickCount 和 g_dwTemp。

2.2 dll模块

dll模块的生命周期与exe模块的生命周期是大致相同的:

1、初始化全局变量;

2、调用 DllMain(...,DLL_PROCESS_ATTACH,...)

3、进程创建了一个新线程,会调用DllMain(...,DLL_THREAD_ATTACH,...)

4、线程(非主线程)结束,会调用DllMain(...,DLL_THREAD_DETACH,...)

5、初始化静态变量;

6、调用 DllMain(...,DLL_PROCESS_DETACH,...)

7、销毁静态变量;

8、销毁全局变量。

如果exe导入了dll,则其生命周期为

1、静态/动态初始化 dll 全局变量,调用 DllMain(...,DLL_PROCESS_ATTACH,...)

2、静态/动态初始化 exe 全局变量

3、exe 调用 main 或 WinMain

4、初始化静态变量;

5、exe 从 main 或 WinMain 返回

6、销毁 exe 静态变量、销毁 exe 全局变量

7、dll 调用 DllMain(...,DLL_PROCESS_DETACH,...)

8、销毁 dll 静态变量、销毁 dll 全局变量

如果E.exe导入了A.dll,后者又导入了B.dll,则运行E.exe时,会首先加载B.dll,然后加载A.dll,最后加载E.exe。

第3章调试WinCE程序

使用VC2005/VC2008调试WinCE程序比EVC++3.0/4.0要方便很多,而且调试效率也比较高。更为重要的是:VC2005/VC2008调试使用的虚拟机非常好,能够直接执行针对ARM芯片编译的执行程序。

如果要调试的执行程序需要额外的动态库文件DacelLib.dll,该怎么办?解决方法有两个,一是调试时将DacelLib.dll部署到模拟器上;二是直接将DacelLib.dll复制到模拟器的共享文件夹内。

3.1 部署附加文件

进入项目属性页,在"配置属性"、"部署"下有附加文件。

图3.1 部署附加文件

下面是附加文件的例子

msvcr90.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0

atl90.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0

msvcr90d.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0

MFC90UD.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0

其格式为:文件名|本机目录|部署目录|是否注册

假定DacelLib.dll位于C:\Share目录,想将其复制到智能设备的\My Documents目录,则应该这样设置:

DacelLib.dll|C:\Share|\My Documents|0

如果DacelLib.dll是一个COM组件,则它需要注册,请将最后的0改为1。

3.2 共享文件夹

如下图所示,单击模拟器的【文件】【配置】菜单项。

图3.2 模拟器

请设置共享文件夹

图3.3 共享文件夹

模拟器上将增加一个类似SD卡的目录——Storage Card。该目录下的内容与上图共享文件夹的内容保持一致。

图3.4 Storage Card目录

VC++调试说明的更多相关文章

  1. VC调试篇

    难怪很多前辈说调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言.不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件. 我以前接触的程序大多是有比较成形的思路和方法,调试起来出 ...

  2. VC++调试基础

    一.调试基础 调试快捷键 F5:  开始调试 Shift+F5: 停止调试 F10:   调试到下一句,这里是单步跟踪 F11:   调试到下一句,跟进函数内部 Shift+F11:  从当前函数中跳 ...

  3. gdb对应vc调试命令

    gdb vc调试对照表: 实现功能                vc                   gdb 修改后编译              f7                   ma ...

  4. VC调试篇:ASSERT(FALSE)时怎么办?查看调用堆栈

    问题简述 我们在调试程序时,经常会遇到程序中断的情况,就像下图这样. 我艹,这该怎么办,我们一下子就懵逼了.我们选择中断,常常会跳到一个莫名其妙的地方去. 正是这个断言 ASSERT(::IsWind ...

  5. vc调试大全

    一.调试基础 调试快捷键 F5:  开始调试 Shift+F5: 停止调试 F10:   调试到下一句,这里是单步跟踪 F11:   调试到下一句,跟进函数内部 Shift+F11:  从当前函数中跳 ...

  6. VC调试方法大全

    VC调试方法大全 一.调试基础 调试快捷键 F5:  开始调试 Shift+F5: 停止调试 F10:   调试到下一句,这里是单步跟踪 F11:   调试到下一句,跟进函数内部 Shift+F11: ...

  7. VC调试笔记

    1.windows-32调试: ①使用map文件根据崩溃地址寻找对应的源代码文件和行号 勾选project->settings->link->General mapfile,对应的P ...

  8. VC++调试错误的解决方案

    这篇文章主要用来记录使用Visual Studio过程中,出现的各种error,并提供自己当时解决的方案.但是,一个error可能由不用原因引起的,文中案例仅供大家参考. nafxcwd.lib(th ...

  9. VC 调试版(Debug Version)和发行版(Release Version)

    调试是纠正或修改代码,使之可以顺利地编译.运行的过程.为此,VC IDE提供了功能强大的调试和跟踪工具. 1.1.1 调试版(Debug Version)和发行版(Release Version) 开 ...

随机推荐

  1. 2016年11月21日 星期一 --出埃及记 Exodus 20:12

    2016年11月21日 星期一 --出埃及记 Exodus 20:12 "Honor your father and your mother, so that you may live lo ...

  2. VC++ 禁止WebBrowser网页跳转时发出的声音和禁止网页上的文字被选择

    转载:http://blog.csdn.net/cometnet/article/details/51082091 #include <urlmon.h> #ifndef FEATURE_ ...

  3. 重定向redirect与跳转forward区别

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DemoResponse.a ...

  4. ①创建项目testpackage ②在pack2.B中添加方法f ③在类A中添加如下三个成员变量:int型的私有变量i float型的变量f double型的公有变量d 在pack1.B的main方法中为对象a的成员变量f和d分别赋值为2和3 在pack2.C的main方法中为对象a的成员变量d赋值为3

    package pack1; public class A { private int i; float f; public double d; public float getF() { retur ...

  5. git生成SSH key

    使用https:// 提交GitHub上的私有项目时,需要每次都输入帐号和密码,比较麻烦. 比如我自己的笔记本,在push的时候我可不想每次都输入这些. 那就使用SSH吧,这个需要在GitHub的帐号 ...

  6. Spring AOP和AspectJ支持

    学了Spring之后发现我都不知道java为何物-- 在这一章中有好几节,讲的切面编程 第一节:在项目中启用Spring的AspectJ注解支持 第二节:用AspectJ注解声明aspect 第三节: ...

  7. arp中间人

    0x00 摘要 在本章第二层攻击当中,我们将进入网络hacking的奇幻之旅.让我们回顾一下,第二层是负责在以太网中,使用MAC地址来发送数据包.除了ARP攻击,我们将探讨交换机是如何应对DOS攻击的 ...

  8. PostgresSql开放局域网访问

    1) 确认已经退掉所有的MASF终端和MSF GUI,然后打开PostgresSQL的启动文件在文件POSTGRESQL_START参数后面添加-h 0.0.0.0,让PostgreSQL启动时绑定到 ...

  9. [Effective Java]第十一章 序列化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  10. 关于js运动的一些总结

    js运动实现,有两种.一种是速度版,另一种是时间版. 速度版是通过对速度的加减乘除,得出元素的运动数据.时间版是通过对时间进行Tween公式运算,得出元素的运动数据. 速度版运动优点:容易在运动过程中 ...