精华内容
下载资源
问答
  • 如题. 成功编译和链接,但点击调试和运行程序没有什么反应,程序执行.
  •  由于控件并不能单独运行,所以你必须利用另一个程序来装载控件并进行调试VC中提供了ActiveX容器供使用,在工程/设置菜单(project/setting)中选择Debug页第一栏Executable for debug session,右侧箭头并选择...

    VC中如何调试和使用ActiveX控件

     

      由于控件并不能单独运行,所以你必须利用另一个程序来装载控件并进行调试,VC中提供了ActiveX容器供使用,在工程/设置菜单(project/setting)中选择Debug页第一栏Executable for debug session,右侧箭头并选择ActiveX Container。

      然后开始调试,进入Container时VC会提示Container中是没有调试代码的错误,不用理会并继续。

      进入Container后首先要装载你所需要调试的控件,选择菜单Edit/Insert OLE Control...,在弹出的对话框中选择你需要插入的控件。

    如果Container 成功创建了控件在屏幕中就会显示出控件,根据上节的内容我们可以看到控件中显示了一串字符,接下来我们需要测试一下控件所提供的方法是否能够正确运行。请选择菜单Edit/Invoke Methods...,在弹出的对话框上选择你要使用的方法,但你选择了方法后,对话框上的参数输入区会显示输入参数的列表,你输入参数后按下 Invoke按钮就可以执行。

      在调试时你可以如同调试其他程序一样在代码中使用TRACE宏,也可以设置断点。

    其实你在插入控件时会看见其他在系统中已经注册的控件,如果有兴趣可以自己试试加载几个看看效果。

    如果要在VC 的工程中使用已经存在的ActiveX控件,最简单的方法就是利用VC的插入功能,在菜单中选择Project/Add To Project/Component and Control(在不同版本的VC中可能菜单位置不同),然后选择插入的控件,VC会为你生成这个控件的定义文件,当然和你最开始编写的会完全不一样,但是没有关系。你会在定义文件看见这个控件所实现的方法和属性,这些都可以让你通过函数的方式进行调用。(所以在使用控件时如果没有该控件的说明是很难使用的)

    还有一种方法就是在对话框中插入一个控件。如果该控件的定义文件没有生成VC也可以帮助你生成。

      在对话框中的控件是不需要手工创建的,但是如果你希望在其他地方创建窗口就需要调用控件的创建函数,其实这个函数很简单,和CWnd::Create函数定义的区别不大。定义为:

     class CATLSam : public CWnd{BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,                  const RECT& rect, CWnd* pParentWnd, UINT nID,                  CFile* pPersist = NULL, BOOL bStorage = FALSE,                  BSTR bstrLicKey = NULL)。可以使用如下方式调用:

    Create("window text",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0,0,200,200),this,1001);

      由于是CWnd的派生类所以CWnd的相关功能都可以使用。在程序中创建了控件窗口后就可以调用控件的各种方法(对属性的控制也是通过函数调用来实现的,在前面的教程中我们已经认识到这点)。

      在控件创建后就可以使用控件的各种属性和方法,由于控件是你自己编写的所以调用起来应该不会有什么问题。

     

    展开全文
  • VC6绝对是老古董了,但是它的风格界面操作便利性,是后来的更高版本所不能替代的,尤其是做一些小程序调试的时候,它还是拥有绝对优势。 个人觉得用Ctrl+W进行消息映射添加变量控件的方法,比后续版本显得更...

    VC6绝对是老古董了,但是它的风格界面和操作便利性,是后来的更高版本所不能替代的,尤其是做一些小程序调试的时候,它还是拥有绝对优势。

    个人觉得用Ctrl+W进行消息映射和添加变量控件的方法,比后续版本显得更方便得多。

    闲话少说,言归正传!

    但是在win10环境下运行VC6,无法按F10、F11进行单步调试,会出现:

    Unhandled exception in ***.exe(OLE32.DLL):0xC0000005:Access Violation
    的错误,如何解决这个问题呢?


    做如下设置即可解决:

    1、菜单Tools->Options中的Debug,Disassembly window下的Source annotation取消
    2、保存设置,然后即可单步调试
    3、再将Tools->Options中的Debug,Disassembly window下的Source annotation勾上(这步可做可不做)

     

     

    展开全文
  • VC代码的编写和调试

    2008-12-05 09:52:00
    使用Visual C++调试调试 一、调试版本与发布版本 有时程序能在调试版本运行不能运行于发布版本,反之也有可能。一般说来,一个发布版本意味着某些类型的优化,而一个调试版本则没有优化。下面我们来看看它们的...
      使用Visual C++调试器调试
     
      一、调试版本与发布版本
     
             有时程序能在调试版本运行但不能运行于发布版本,反之也有可能。一般说来,一个发布版本意味着某些类型的优化,而一个调试版本则没有优化。下面我们来看看它们的区别:
     
      1、特别针对调试版本的编译选项
     
             (1)/MDd,/MLd或者/MTd
     
             调试版本的运行时刻库有调试符号,使用了调试堆,调试堆的目的是发现内存破坏和内存泄漏,并且向用户报告源代码的哪个地方出了问题。特性:
     
             .调试版本的运行时刻库对内存的分配作了跟踪,允许用户检查内存泄漏。
     
             .在刚分配的内存里写上0xCD的字节模式,用0xCD来填充刚分配的内存,有助于发现数据未被初始化的错误。
     
             .在被释放的内存写上0xDD的字节模式,有助于发现已被释放的内存。
     
             .在缓冲区的两边分配了四字节的保护数据,并用0xFD的字节模式作初始化,来检查写内存的上溢出和下溢出。
     
             .在每个内存分配的地方对源代码文件名和行号作了记录,有助于用户在源代码中对内存分配进行定位。
     
             (2)/Od
     
          这个选项用来关闭优化开关。因为未被优化的代码直接对应于源代码,所以比优化后的代码更容易读懂。未被优化的代码编译和链接会更快,会有更短的调试周期。而由于优化,发布版本不见得会比调试版本运行得好,优化代码要求编译器做一些假设,去除冗余,但有时这个假设是错误的,并且去掉的冗余也有可能隐藏错误。如发布版本的帧指针(EBP寄存器)省略(FPO)隐藏了函数原型不匹配的错误;在同步异常模式(只能由throw语句抛出,编译器默认,由 /GX编译选项设置)下,异常处理程序可能被优化掉,会阻止程序中的C++异常处理代码安全地捕获结构异常,在这种情况下,你必须使用异步异常模式(采取任何指令都会产生异常的机制,由/Eha编译选项设置)。
     
             (3)/D “_DEBUG”
     
      打开条件编译调试代码开关。只有这个符号被定义,调试代码才会被编译,MFC使用_DEBUG符号来确定到底链接的是哪个版本的MFC类库。在调试版本中,内联默认情况下是被关闭的。
     
             (4)/ZI
     
      创建编辑继续(Edit and Continue)的程序数据库。这个选项会打开/GF编译选项,/GF编译选项会消除重复字符串,并将字符串放到只读内存。编辑继续功能需要获取存储在 PDB文件里的特殊信息来使得代码的修改对调试器有效。如果被修改文件对应的信息不在PDB文件里,编辑继续功能就不能进行,而且在调试过程中对代码的任何修改都会出现下面的提示信息“One or more files are out of date or do not exist.”。
     
             (5)/GZ
     
      在调试版本中用来发现那些在发布版本里才发现的错误。其作用如下:
     
             .用0xCC模式初始化自动(本地)变量。
     
             .在通过函数指针调用函数时,检查栈指针,确认是否有调用规则不匹配。
     
             .在函数最后检查栈指针是否被改变。
     
             (6)/Gm
     
      打开最小化重新链接开关,减少链接时间。
     
      2、特别针对发布版本的编译选项
     
             (1)/MD,/ML或者/MT
     
      使用发布版本的运行时刻库。
     
             (2)/O1或者/O2
     
      打开优化开关,使得程序会最小或说速度会最快,优化器还可能发现代码中潜在的错误,而这些错误可能会被调试版本掩盖。
     
             (3)/D “NDEBUG”
     
      关闭条件编译调试代码开关。
     
             (4)/GF
     
      消除重复字符串并将它们放到只读内存中以避免被错误地修改。
     
             (5)/Zi
     
      创建包含调试符号的程序数据库。
     
             如果一个错误只发生在发布版本里,除非你是个汇编高手,否则你需要调试符号来提示你到底程序出现了什么问题,调试符号保存在程序的数据库文件(PDB)中。Visual C++的AppWizard默认情况下没有为发布版本创建调试符号。为创建调试符号,打开工程设置对话框,选择Win32 Release,在C/C++标签里选择Common类,在调试信息里,如果是发布版本选择Program Database,如果是调试版本选择Program Database for Edit and Continue(编辑继续选项与优化链接不相容,不适于发布版本)。在Link标签里选择Debug类,然后选择Debug Info和Microsoft format选项,最好不要选择Separate types选项,这样所有的调试信息才会被合并到单独的一个PDB文件中。对于发布版本,选择Link标签,在Project options对话框的最后加上“/OPT:REF”,这个选项使得不被引用的函数和数据不会出现在可执行文件中,避免了文件的无谓增大。对于调试版本不要使用这个选项,它会关闭增量链接(incremental linking)。
     
      二、Visual C++编辑器的“设置”菜单
     
      当你打开或新建一个包含至少一个工程的Workspace后,Visual C++的Project菜单中的“Settings…”命令就变为有效,选择它或者按下热键Alt+F7后,便可调出工程设置对话框,这里面的选项将影响整个工程的建立和调试过程,因此很重要。
     
      在这个对话框中,左上方的下拉列表框用于选择一种工程配置,包括有Win32 Debug、Win32 Release和All Configurations(指前两种配置一起),某些选项在不同的工程配置中有不同的缺省值。左边的树形视图给出了当前工程所有的文件及分类情况。下面我们就以Win32 Debug为例来看看与工程有关的的四个主要选项卡的各自功能与含义(一共有十个选项卡):
     
      1、 General选项卡
     
      这个选项卡比较简单,从上向下的第一个选项用于更改使用MFC类库的方式: DLL的方式或是静态连接。我们可以在两种方式之间进行切换。第二个选项用于指定在编译连接过程中生成的中间文件和输出文件的存放目录,对于调试版本来说,缺省的目录是工程下面的“Debug”子目录。第三个选项用于指定是否允许每种工程配置都有自己的文件依赖关系(主要指头文件),由于绝大多数工程的调试版本和发布版本都具有相同的文件依赖关系,所以通常不需要更改该选项。
     
      2、 Debug选项卡
     
      Debug选项卡中是一些与调试有关的选项,由于选项比较多,它们被分成了几个类,我们可以从Category中选择不同的类别,选项卡就会切换显示出相应的选项。
     
      在General类别中,可以指定要调试的可执行文件名。另外三个选项可以指定用于调试的工作目录,开始调试时给程序传送的命令行参数,以及进行远程调试时可执行文件的路径。
     
      3、C/C++选项卡
     
      C/C++选项卡控制着Visual C++的编译器,其中的选项比较多。下面有一个Project Options编辑框,里面列出的各种命令开关将会在开始编译时作为命令行参数传送给Visual C++的编译器。这些命令开关会跟随其它选项改变而改变。
     
      在General类别中,Warning level用于指定编译器显示警告的级别,如果选中了Warnings as errors,那么显示的每一个警告都将会引起一个错误,这样在编译完毕后就无法启动连接器来进行连接。Optimizations用于设置代码优化方式,优化的目的主要有提高运行速度和减小程序体积两种,但有时候这两种目的是相互矛盾的。另外,在极少数情况下,不进行优化,程序能正常运行,打开了优化措施之后,程序却会出现一些莫名其妙的问题。其实这多半是程序中有潜在的错误,关闭优化措施往往只是暂时解决问题。Debug info用于指定编译器产生的调试信息的类型,为了使用Visual C++的即编即调功能,必须在这里选择生成“Program Database for Edit and Continue”类型的调试信息。Preprocessor definitions是一些预先定义的宏名。
     
      C++ Language类别中的选项涉及到了C++语言的一些高级特性,包括有成员指针的表示方式、异常处理、运行时类型信息,一般情况下都不用改变它们。 Code Generation类别中的选项涉及如何生成目标代码,一般情况下保持缺省值即可。在Customize类别中,从上到下六个选项的含义分别为:是否禁止使用Microsoft对C++的扩展;是否允许函数级别的连接;是否消除重复的字符串;是否允许进行最小化的重建;是否允许递增编译方式;是否允许编译器在开始运行时向Output窗口中输出自己的版本信息。
     
      在Listing Files类别中,我们可以指定编译器生成浏览信息和列表文件(Listing file),前者可由浏览信息维护工具BSCMAKE生成浏览信息文件,后者则包含了C/C++源文件经过编译后对应的汇编指令。 Optimizations类别允许我们对优化措施进行更细微的控制,选择了Customize后,便可以选择进行哪几项优化,在Inline function expansion中我们可以指定对内联函数的扩展方式。Precompiled Headers类别中是关于预编译头文件的一些选项,一般情况下都不用更改。Preprocessor类别中是关于预处理的一些选择。
     
      4、Link 选项卡
     
      Link选项卡控制着Visual C++的连接器。在General类别中,可以指定输出的文件名,以及一些在连接过程中需要使用的额外的库文件或目标文件,下边五个选项的含义分别为:生成调试信息;忽略所有缺省的库文件;允许递增连接方式(这种方式可以加快连接的速度);生成MAP文件;允许进行性能分析。在Customize中选中 Use program database允许使用程序数据库。在Debug类别中,我们可以指定调试信息的类别是Microsoft的格式,还是COFF格式,或者两种都有,选中Separate types后连接器会把调试信息分开放在PDB文件中,这样连接起来会更快一些,但调试时速度却会慢一些。Input类别中是一些与输入库文件有关的选项,我们可以在这里指定使用或不使用某些库文件或目标文件。Output类别中则是一些与最终输出的可执行文件有关的选项,一般情况下都不用改变。
     
      三、Visual C++调试工具
     
      1、调试窗口
     
             (1)观察窗口(Watch)
     
             调试程序时,可使用观察窗口监视变量和表达式。
     
             (2)快速查看窗口(Quick watch)
     
             功能和观察窗口差不多。
     
             (3)变量窗口(Variables)
     
             变量窗口有三个标签:Auto标签显示了当前语句和前一条语句用到的变量,Locals标签显示当前函数的局部变量,this标签显示了this指针执行的对象。
     
             (4)寄存器窗口(Register)
     
             可以监视CPU的寄存器、标志值以及浮点堆栈
     
             (5)内存窗口(Memory)
     
             可显示从一特定地址开始的虚拟内存。Address框允许你指定从哪个虚拟内存地址开始显示。
     
             (6)调用栈窗口(Call stack)
     
             可显示引起当前源代码语句执行的一系列函数调用,当前函数在堆栈的顶端。
     
             (7)反汇编窗口(Disassembly)
     
             可查看编译器生成的对应于源代码的汇编指令。
     
      2、调试符号
     
             程序数据库文件(.pdb)包含了Visual C++调试器所需的调试信息和程序信息。调试信息包含了变量的名字和类型、函数原型、源代码行号、类和结构的布局、FPO调试信息(重建堆栈帧)以及进行增量链接所需的信息。对于设置了Program Database for Edit and Continue选项的程序,PDB还要包含执行编辑继续功能所需的信息。
     
      3、使用断点
     
             断点(BreakPoint)是运行你向调试器描述环境,并让调试器设置好程序状态的一种机制。如果没有断点,只有在程序里一步一步跟踪使用调试器。在Visual C++中,你可以设置三种类型的断点:代码定位断点、数据断点和消息断点。
     
      四、提高调试器的查错能力
     
             尽量采用编译时刻检查而不是运行时刻检查。
     
      1、使用最高的编译警告级别/W4
     
             象if(x=2)这样的语句,默认的警告级别为/W3时不显示任何信息,但改成最高警告级别/W4时则会出现“waning C4706:assignment within conditional expression”的警告。/W4能给出一些/W3所不能给的警告。

     2、在调试版本中使用/GZ编译选项
     
             /GZ选项用来发现那些在发布版本里才发现的错误,包括未被初始化的自动(局部)变量、堆栈错误、不正确的函数原型等。
     
      3、使用#pragma warning编译器指示
     
             你可以使用#pragma warning编译器指示来禁止整个程序、特定的头文件、特定的代码文件或是特定的某一行代码的特定警告,这看你把#pragma放在哪里。
     
      4、使用没有警告的编译法则/WX
     
             这个编译选项把所有的警告当成错误来对待,只有在假警告被消除之后才能应用。有时编译警告可能是合理的,处理编译警告的核心是要发现错误,而不是抑制警告本身。这个法则对于大的程序开发小组来说很有帮助。最终目标是消除错误,而不是消除警告。
     
      五、内存空间与分配
     
             1、内存分配错误
     
             动态内存分配错误有两种基本类型:内存错误和内存泄漏。
     
      (1)内存错误
     
      当一个指针或者该指针所指向的内存单元成为无效单元,或者内存中分配的数据结构被破坏时,就会造成内存错误。指针未被初始化,指针被初始化为一个无效地址,指针被不小心错误地修改,在与指针相关联的内存区域被释放后使用该指针(这种指针被称为虚悬(dangling)指针),这些都会使指针变为无效指针。当通过一个错误指针或者虚悬指针对内存进行写入,或者将指针强制转换为不匹配的数据结构,又或者是写数据越界,内存自身也会遭到破坏。删除未被初始化的指针、删除非堆指针、多次删除同一指针或者覆盖一个指针的内部数据结构,都会造成内存分配系统错误。
     
      (2)内存泄漏
     
      内存泄漏在被动态分配的内存没有被释放时产生。有许多情况会导致内存泄漏,如没有在程序的全部执行路径中释放内存,没有在析构函数中释放所有的内存等。一个程序在崩溃之前可运行的时间越长,则导致崩溃的原因与内存泄漏的关系越大。
     
      Windows会在程序结束的时候将泄漏的内存收回,因此内存泄漏是个暂时性的问题。但为什么必须消除内存泄露呢?首先,内存泄漏往往会导致系统资源的泄漏。动态分配内存往往不仅仅代表一块存储区域,还代表了某些类型的系统资源,如文件、窗口、设备上下文、GDI对象等。其次,高质量的程序和特定的服务器程序必须能够无限地运行下去。最后,内存泄漏往往是其他程序错误或不良编程习惯的征兆。
     
      导致内参泄漏的原因:忘记释放内存;构造函数失败;存在内存泄漏的析构函数;存在内存泄漏的异常处理程序;多个返回语句;使用错误形式的delete。
     
      2、关于内存的初始化
     
             在调试版本里,堆里未被初始化的内存被0xCD字节模式填充,堆里释放的内存被0xDD字节模式填充。堆栈里被初始化的内存被0xCC字节模式填充。调试版本和发布版本里,未被初始化的全局内存都被初始化为0。
     
      3、内存虚拟地址空间
     
             Windows使用一组固定的范围来分割进程的4GB虚拟地址空间,因此有时可通过查看指针的返回值来判断指针是否有效。
     
      (1)Windows2000虚拟地址空间划分
     
      0~0XFFFF(64KB):不能用来检测空指针赋值(访问冲突)
     
      0x10000(64KB)~0x7FFEFFFF(2GB-64KB):Win32进程私有的(非保留的),用于程序代码和数据
     
      0x7FFF0000(2GB-64KB)~0x7FFFFFFF(2GB):不能用来防止覆盖OS分区(访问冲突)
     
      0x800000000(2GB)~0xFFFFFFFF(4GB):为操作系统保留,不可访问(访问冲突)
    展开全文
  • 串口调试精灵是 VC编写,运行需要其它任何文件,完全绿色软件,方便跨平台使用。极好的串口调试程序,稳定用于 Win9X/NT 平台,提高工作效率,使串口调试能够方便透明的进行。它可以在线设置各种通讯速率、...
  • 关于VC代码的编写和调试(三)

    千次阅读 2003-03-15 10:17:00
    使用Visual C++调试调试一、调试版本与发布版本 有时程序能在调试版本运行不能运行于发布版本,反之也有可能。一般说来,一个发布版本意味着某些类型的优化,而一个调试版本则没有优化。下面我们来看看它们的...
     
    

    使用Visual C++调试器调试

    一、调试版本与发布版本

           有时程序能在调试版本运行但不能运行于发布版本,反之也有可能。一般说来,一个发布版本意味着某些类型的优化,而一个调试版本则没有优化。下面我们来看看它们的区别:

    1、特别针对调试版本的编译选项

           1/MDd,/MLd或者/MTd

           调试版本的运行时刻库有调试符号,使用了调试堆,调试堆的目的是发现内存破坏和内存泄漏,并且向用户报告源代码的哪个地方出了问题。特性:

           .调试版本的运行时刻库对内存的分配作了跟踪,允许用户检查内存泄漏。

           .在刚分配的内存里写上0xCD的字节模式,用0xCD来填充刚分配的内存,有助于发现数据未被初始化的错误。

           .在被释放的内存写上0xDD的字节模式,有助于发现已被释放的内存。

           .在缓冲区的两边分配了四字节的保护数据,并用0xFD的字节模式作初始化,来检查写内存的上溢出和下溢出。

           .在每个内存分配的地方对源代码文件名和行号作了记录,有助于用户在源代码中对内存分配进行定位。

           2/Od

        这个选项用来关闭优化开关。因为未被优化的代码直接对应于源代码,所以比优化后的代码更容易读懂。未被优化的代码编译和链接会更快,会有更短的调试周期。而由于优化,发布版本不见得会比调试版本运行得好,优化代码要求编译器做一些假设,去除冗余,但有时这个假设是错误的,并且去掉的冗余也有可能隐藏错误。如发布版本的帧指针(EBP寄存器)省略(FPO)隐藏了函数原型不匹配的错误;在同步异常模式(只能由throw语句抛出,编译器默认,由/GX编译选项设置)下,异常处理程序可能被优化掉,会阻止程序中的C++异常处理代码安全地捕获结构异常,在这种情况下,你必须使用异步异常模式(采取任何指令都会产生异常的机制,由/Eha编译选项设置)。

           3/D “_DEBUG”

    打开条件编译调试代码开关。只有这个符号被定义,调试代码才会被编译,MFC使用_DEBUG符号来确定到底链接的是哪个版本的MFC类库。在调试版本中,内联默认情况下是被关闭的。

           4/ZI

    创建编辑继续(Edit and Continue)的程序数据库。这个选项会打开/GF编译选项,/GF编译选项会消除重复字符串,并将字符串放到只读内存。编辑继续功能需要获取存储在PDB文件里的特殊信息来使得代码的修改对调试器有效。如果被修改文件对应的信息不在PDB文件里,编辑继续功能就不能进行,而且在调试过程中对代码的任何修改都会出现下面的提示信息“One or more files are out of date or do not exist.”。

           5/GZ

    在调试版本中用来发现那些在发布版本里才发现的错误。其作用如下:

           .0xCC模式初始化自动(本地)变量。

           .在通过函数指针调用函数时,检查栈指针,确认是否有调用规则不匹配。

           .在函数最后检查栈指针是否被改变。

           6/Gm

    打开最小化重新链接开关,减少链接时间。

    2、特别针对发布版本的编译选项

           1/MD,/ML或者/MT

    使用发布版本的运行时刻库。

           2/O1或者/O2

    打开优化开关,使得程序会最小或说速度会最快,优化器还可能发现代码中潜在的错误,而这些错误可能会被调试版本掩盖。

           3/D “NDEBUG”

    关闭条件编译调试代码开关。

           4/GF

    消除重复字符串并将它们放到只读内存中以避免被错误地修改。

           5/Zi

    创建包含调试符号的程序数据库。

           如果一个错误只发生在发布版本里,除非你是个汇编高手,否则你需要调试符号来提示你到底程序出现了什么问题,调试符号保存在程序的数据库文件(PDB)中。Visual C++AppWizard默认情况下没有为发布版本创建调试符号。为创建调试符号,打开工程设置对话框,选择Win32 Release,在C/C++标签里选择Common类,在调试信息里,如果是发布版本选择Program Database,如果是调试版本选择Program Database for Edit and Continue(编辑继续选项与优化链接不相容,不适于发布版本)。在Link标签里选择Debug类,然后选择Debug InfoMicrosoft format选项,最好不要选择Separate types选项,这样所有的调试信息才会被合并到单独的一个PDB文件中。对于发布版本,选择Link标签,在Project options对话框的最后加上“/OPT:REF”,这个选项使得不被引用的函数和数据不会出现在可执行文件中,避免了文件的无谓增大。对于调试版本不要使用这个选项,它会关闭增量链接(incremental linking)

    二、Visual C++编辑器的“设置”菜单

    当你打开或新建一个包含至少一个工程的Workspace后,Visual C++Project菜单中的“Settings…”命令就变为有效,选择它或者按下热键Alt+F7后,便可调出工程设置对话框,这里面的选项将影响整个工程的建立和调试过程,因此很重要。

    在这个对话框中,左上方的下拉列表框用于选择一种工程配置,包括有Win32 DebugWin32 ReleaseAll Configurations(指前两种配置一起),某些选项在不同的工程配置中有不同的缺省值。左边的树形视图给出了当前工程所有的文件及分类情况。下面我们就以Win32 Debug为例来看看与工程有关的的四个主要选项卡的各自功能与含义(一共有十个选项卡):

    1 General选项卡

    这个选项卡比较简单,从上向下的第一个选项用于更改使用MFC类库的方式: DLL的方式或是静态连接。我们可以在两种方式之间进行切换。第二个选项用于指定在编译连接过程中生成的中间文件和输出文件的存放目录,对于调试版本来说,缺省的目录是工程下面的“Debug”子目录。第三个选项用于指定是否允许每种工程配置都有自己的文件依赖关系(主要指头文件),由于绝大多数工程的调试版本和发布版本都具有相同的文件依赖关系,所以通常不需要更改该选项。

    2 Debug选项卡

    Debug选项卡中是一些与调试有关的选项,由于选项比较多,它们被分成了几个类,我们可以从Category中选择不同的类别,选项卡就会切换显示出相应的选项。

    General类别中,可以指定要调试的可执行文件名。另外三个选项可以指定用于调试的工作目录,开始调试时给程序传送的命令行参数,以及进行远程调试时可执行文件的路径。

    3C/C++选项卡

    C/C++选项卡控制着Visual C++的编译器,其中的选项比较多。下面有一个Project Options编辑框,里面列出的各种命令开关将会在开始编译时作为命令行参数传送给Visual C++的编译器。这些命令开关会跟随其它选项改变而改变。

    General类别中,Warning level用于指定编译器显示警告的级别,如果选中了Warnings as errors,那么显示的每一个警告都将会引起一个错误,这样在编译完毕后就无法启动连接器来进行连接。Optimizations用于设置代码优化方式,优化的目的主要有提高运行速度和减小程序体积两种,但有时候这两种目的是相互矛盾的。另外,在极少数情况下,不进行优化,程序能正常运行,打开了优化措施之后,程序却会出现一些莫名其妙的问题。其实这多半是程序中有潜在的错误,关闭优化措施往往只是暂时解决问题。Debug info用于指定编译器产生的调试信息的类型,为了使用Visual C++的即编即调功能,必须在这里选择生成“Program Database for Edit and Continue”类型的调试信息。Preprocessor definitions是一些预先定义的宏名。

    C++ Language类别中的选项涉及到了C++语言的一些高级特性,包括有成员指针的表示方式、异常处理、运行时类型信息,一般情况下都不用改变它们。Code Generation类别中的选项涉及如何生成目标代码,一般情况下保持缺省值即可。在Customize类别中,从上到下六个选项的含义分别为:是否禁止使用MicrosoftC++的扩展;是否允许函数级别的连接;是否消除重复的字符串;是否允许进行最小化的重建;是否允许递增编译方式;是否允许编译器在开始运行时向Output窗口中输出自己的版本信息。

    Listing Files类别中,我们可以指定编译器生成浏览信息和列表文件(Listing file),前者可由浏览信息维护工具BSCMAKE生成浏览信息文件,后者则包含了C/C++源文件经过编译后对应的汇编指令。Optimizations类别允许我们对优化措施进行更细微的控制,选择了Customize后,便可以选择进行哪几项优化,在Inline function expansion中我们可以指定对内联函数的扩展方式。Precompiled Headers类别中是关于预编译头文件的一些选项,一般情况下都不用更改。Preprocessor类别中是关于预处理的一些选择。

    4Link 选项卡

    Link选项卡控制着Visual C++的连接器。在General类别中,可以指定输出的文件名,以及一些在连接过程中需要使用的额外的库文件或目标文件,下边五个选项的含义分别为:生成调试信息;忽略所有缺省的库文件;允许递增连接方式(这种方式可以加快连接的速度);生成MAP文件;允许进行性能分析。在Customize中选中Use program database允许使用程序数据库。在Debug类别中,我们可以指定调试信息的类别是Microsoft的格式,还是COFF格式,或者两种都有,选中Separate types后连接器会把调试信息分开放在PDB文件中,这样连接起来会更快一些,但调试时速度却会慢一些。Input类别中是一些与输入库文件有关的选项,我们可以在这里指定使用或不使用某些库文件或目标文件。Output类别中则是一些与最终输出的可执行文件有关的选项,一般情况下都不用改变。

    三、Visual C++调试工具

    1、调试窗口

           1)观察窗口(Watch)

           调试程序时,可使用观察窗口监视变量和表达式。

           2)快速查看窗口(Quick watch)

           功能和观察窗口差不多。

           3)变量窗口(Variables)

           变量窗口有三个标签:Auto标签显示了当前语句和前一条语句用到的变量,Locals标签显示当前函数的局部变量,this标签显示了this指针执行的对象。

           4)寄存器窗口(Register)

           可以监视CPU的寄存器、标志值以及浮点堆栈

           5)内存窗口(Memory)

           可显示从一特定地址开始的虚拟内存。Address框允许你指定从哪个虚拟内存地址开始显示。

           6)调用栈窗口(Call stack)

           可显示引起当前源代码语句执行的一系列函数调用,当前函数在堆栈的顶端。

           7)反汇编窗口(Disassembly)

           可查看编译器生成的对应于源代码的汇编指令。

    2、调试符号

           程序数据库文件(.pdb)包含了Visual C++调试器所需的调试信息和程序信息。调试信息包含了变量的名字和类型、函数原型、源代码行号、类和结构的布局、FPO调试信息(重建堆栈帧)以及进行增量链接所需的信息。对于设置了Program Database for Edit and Continue选项的程序,PDB还要包含执行编辑继续功能所需的信息。

    3、使用断点

           断点(BreakPoint)是运行你向调试器描述环境,并让调试器设置好程序状态的一种机制。如果没有断点,只有在程序里一步一步跟踪使用调试器。在Visual C++中,你可以设置三种类型的断点:代码定位断点、数据断点和消息断点。

    四、提高调试器的查错能力

           尽量采用编译时刻检查而不是运行时刻检查。

    1、使用最高的编译警告级别/W4

           if(x=2)这样的语句,默认的警告级别为/W3时不显示任何信息,但改成最高警告级别/W4时则会出现“waning C4706:assignment within conditional expression”的警告。/W4能给出一些/W3所不能给的警告。

    2、在调试版本中使用/GZ编译选项

           /GZ选项用来发现那些在发布版本里才发现的错误,包括未被初始化的自动(局部)变量、堆栈错误、不正确的函数原型等。

    3、使用#pragma warning编译器指示

           你可以使用#pragma warning编译器指示来禁止整个程序、特定的头文件、特定的代码文件或是特定的某一行代码的特定警告,这看你把#pragma放在哪里。

    4、使用没有警告的编译法则/WX

           这个编译选项把所有的警告当成错误来对待,只有在假警告被消除之后才能应用。有时编译警告可能是合理的,处理编译警告的核心是要发现错误,而不是抑制警告本身。这个法则对于大的程序开发小组来说很有帮助。最终目标是消除错误,而不是消除警告。

    五、内存空间与分配

           1、内存分配错误

           动态内存分配错误有两种基本类型:内存错误和内存泄漏。

    1)内存错误

    当一个指针或者该指针所指向的内存单元成为无效单元,或者内存中分配的数据结构被破坏时,就会造成内存错误。指针未被初始化,指针被初始化为一个无效地址,指针被不小心错误地修改,在与指针相关联的内存区域被释放后使用该指针(这种指针被称为虚悬(dangling)指针),这些都会使指针变为无效指针。当通过一个错误指针或者虚悬指针对内存进行写入,或者将指针强制转换为不匹配的数据结构,又或者是写数据越界,内存自身也会遭到破坏。删除未被初始化的指针、删除非堆指针、多次删除同一指针或者覆盖一个指针的内部数据结构,都会造成内存分配系统错误。

    2)内存泄漏

    内存泄漏在被动态分配的内存没有被释放时产生。有许多情况会导致内存泄漏,如没有在程序的全部执行路径中释放内存,没有在析构函数中释放所有的内存等。一个程序在崩溃之前可运行的时间越长,则导致崩溃的原因与内存泄漏的关系越大。

    Windows会在程序结束的时候将泄漏的内存收回,因此内存泄漏是个暂时性的问题。但为什么必须消除内存泄露呢?首先,内存泄漏往往会导致系统资源的泄漏。动态分配内存往往不仅仅代表一块存储区域,还代表了某些类型的系统资源,如文件、窗口、设备上下文、GDI对象等。其次,高质量的程序和特定的服务器程序必须能够无限地运行下去。最后,内存泄漏往往是其他程序错误或不良编程习惯的征兆。

    导致内参泄漏的原因:忘记释放内存;构造函数失败;存在内存泄漏的析构函数;存在内存泄漏的异常处理程序;多个返回语句;使用错误形式的delete

    2、关于内存的初始化

           在调试版本里,堆里未被初始化的内存被0xCD字节模式填充,堆里释放的内存被0xDD字节模式填充。堆栈里被初始化的内存被0xCC字节模式填充。调试版本和发布版本里,未被初始化的全局内存都被初始化为0

    3、内存虚拟地址空间

           Windows使用一组固定的范围来分割进程的4GB虚拟地址空间,因此有时可通过查看指针的返回值来判断指针是否有效。

    1Windows2000虚拟地址空间划分

    0~0XFFFF(64KB):不能用来检测空指针赋值(访问冲突)

    0x10000(64KB)~0x7FFEFFFF(2GB-64KB)Win32进程私有的(非保留的),用于程序代码和数据

    0x7FFF0000(2GB-64KB)~0x7FFFFFFF(2GB):不能用来防止覆盖OS分区(访问冲突)

    0x800000000(2GB)~0xFFFFFFFF(4GB):为操作系统保留,不可访问(访问冲突)

    2Windows2000虚拟地址空间使用

    0x00030000~0x0012FFFF:线程栈

    0x00130000~0x003FFFFF:堆(有时堆位于此处)

    0x00400000~0x005FFFFF:可执行代码

    0x00600000~0x0FFFFFFF:堆(有时堆位于此处)

    0x10000000~0x5FFFFFFFApp DLLsMsvcrt.dllMfc42.dll

    0x77000000~0xFFFFFFFFAdvapi32.dllComctl32.dllGdi32.dllKernel32.dllNtdll.dllRpcrt4.dllShell32.dllUser32.dll

    其中,0x00400000是所有版本的Windows能使用的最低基地址。

    六、一些调试技术

    1、调试死循环

           使用Debug菜单下的Break命令。在Windows2000中,如果程序有输入请求,可以使用F12键中断程序,然后检查窗口的调用栈,或单步跟踪代码找到死循环的发生原因。

    2、用Spy++调试与消息有关的问题

           调试消息的最好方案是使用Visual C++提供的Spy++工具。Spy++允许程序员查看窗口、消息、进程和线程。Spy++默认的消息输出:第一栏显示行号。第二栏显示接受消息的句柄。第三栏中的“S”表示消息是用SendMessage发出的,“P”代表消息是由PostMessage发出的,“R”是消息句柄的返回值。第四栏给出解码后的消息名,消息参数或返回值。

    3、非常规方法

    1)重新编连你的应用程序

           当你的程序表现出异常的或意外的行为,或者Visual C++编译器因为一个内部编译器错误而失败时,最好删除工程中的DebugRelease文件夹,从头开始重新进行编连。

    2)重新启动Visual C++

           Visual C++有超强的能力,但编译器的某些特性也会引起奇怪的错误。如果你的程序表现得很奇怪,你可是试着清除所有的断点,关闭或隐藏观察窗口,检查工程设置对话框看最近做了什么修改,直至重新启动Visual C++以便消除由于Visual C++环境引起的异常行为。

    3)重新启动Windows

           当你发现Windows或者其他程序表现出异常的或出人意料的行为时,就应该重新启动Windows,以消除操作系统给调试带来的干扰。

     

    (完)

     

    [参考文献]

    Everett N.McKayMike Woodring著,何健辉,许俊鹃,董伟译.Debugging Windows ProgramsWindows程序调试).北京:中国电力出版社.2002

     

    后记

    Windows 程序调试》这本书中介绍了许多调试的基本知识和技巧。这当中的有些问题,在我看这本书前曾使我百思不得其解,如运行应用程序时,忽然跳出一个对话框,说某段内存为"Write",看了这本书之后你就会明白产生的机理所在。本文对书中相同主题的内容做了一定的抽象概括,对书中前后相关的内容做了整理,并适当补充了一些书中没有的内容。由于自己所关注的方面并未涉及到多线程和COM,因此对这方面的调试技术可参考源书。
    展开全文
  • vc调试多个exe

    2012-04-05 22:42:53
    现在,我想调试c,但是c只能被A调用,不能单独运行。我想将ac两个工程一起调试,请问有什么办法?  首先vc一般新建一个项目(workspace)都是一个project,  如果需要多个工程:  方法1:新建一个工程,然后...
  • vc调试多个exe

    2007-10-17 16:24:00
    现在,我想调试c,但是c只能被A调用,不能单独运行。我想将ac两个工程一起调试,请问有什么办法?首先vc一般新建一个项目(workspace)都是一个project, 如果需要多个工程: 方法1:新建一个工程,然后选中“add to...
  • 转载1:http://www.2cto.com/kf/201111/110829.html 转载2:... 本人使用环境:1、vc2010,qq浏览器  2、vc2010对话框工程   补充转载1:只能运行不能单步调试。 补充转
  • 今天想 调试一下子集算法,但是却不能调试,提示如下图:   通过阅读提示,应该是权限问题,因此我用管理员身份运行vc6.0,结果就可以调试了。开心。...
  • VC调试:两个有个性的bug

    千次阅读 2008-11-23 12:14:00
    昨天在用VC调试cnbook时碰到两个有个性的bug:bug1仅在直接运行Release版本时出现,用F5运行... 1 bug1Release版本调试这个bug不能调试器。我用加打印的方式调试。对于GUI程序,将打印输出送到另一个窗口就可以
  • 在使用ODE物理引擎Direct3d做了一个程序后发现经常出现在调试程序时用Ctrl+F5运行出错,而用F5调试运行没有问题的情况,定位错误实在是难找,很简单的程序,知道,到底是哪里出了问题,导致的程序崩溃。 崩溃时的...
  • VC6 调试 IE 控件 ocx 断点无法进入

    千次阅读 2013-07-16 19:51:29
    原因:IE默认使用多进程打开网页,debug启动的IE进程加载ocx的IE进程不是一个进程,所以不能进入断点。 解决方案: 通过修改注册表将IE改为单进程打开网页: 1. 点击【开始】->【运行】 命令:regedit. ...
  • 在gcc中的使用调试版c++运行

    千次阅读 2016-09-06 20:07:09
    在gcc中的使用调试版c++运行库背景vc中的debugrelease版很大的一个区别就是他们会分别链接debugrelease版的c/c++运行库,而且之间相互不能混用。debug版的c++运行库能够对一些无效迭代器、越界等行为提供检查,...
  • 调试不能正确引入符号表

    千次阅读 2007-06-06 14:01:00
    问题 调试包含其他库(如:MFC、ACE、MYSQL)的工程时,常常会遇到无法找到符号表的情况。...来龙去脉 可执行文件(*.exe*.dll)静态库的调试版本中包含符号表文件的路径,而符号表文件则包含相应符号的源文件路径等
  • 返回值可以指示正常不正常的函数运行,但不能阻止线程的继续运行。.返回值很容易被忽略。.返回值在典型情况下是一个整数,通常映射符合于一个预定义的值。.返回值能高效地传递接收。因此,返回值最适合
  • 如何调试和使用ActiveX控件

    千次阅读 2009-09-08 10:04:00
     由于控件并不能单独运行,所以你必须利用另一个程序来装载控件并进行调试VC中提供了ActiveX容器供使用,在工程/设置菜单(project/setting)中选择Debug页并选择ActiveX Container。 然后开始调试,进入Container...
  • 下载了VC++2008速成版,写...vc 05/08版本都不能直接打开cpp文件来直接编译的。有2种解决方法1、新建:需要先建立工程文件,再写代码。2、添加:文件->项目/解决方案->文件 选择.dsp的工程文件加载,就可以调试运行啦 
  • void push(char a)//因为有多位数的运算因此不能一压栈就提升栈顶指针 { num[top]=num[top]*10+(a-'0'); } double pop()//弹栈函数 弹掉栈顶元素 栈顶归0 top指针下降 { top--; double number=num[top]; ...
  • 1、确定Debug版无错,注意Trace等调试方法可能造成的错误2、Release版的exe文件链接的是标准的MFC...而Debug版不能,除非使用静态链接3、生成release版的步骤:“工程”——“配置”——“常规”——“使用MFC作为静...
  • 算是发布版本,RELEASE下不能调试,生成的文件更小,编译器生成的程序速度更快但是Debug下生成的exe文件在单独运行时需要编译器提供的一些库文件的支持,Release则是不需要的 转载于:...
  • Release版本算是发布版本,Release下不能调试,生成的文件更小,编译器生成的程序速度更快。而且Release版本进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 二、Debug下生成...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 208
精华内容 83
关键字:

vc不能调试和运行