1.概述:
- 介绍如何利用VisualStudio的调试属性,各类端点的设置,利用pdb与dump文件来定位崩溃问题
2.调试工程配置:
- 调试属性设置:工程的调试属性中,我们可以对调试的程序目录及路径进行设置。
- 命令:通常为运行的EXE程序,例如当我们调试DLL工程时,我们的调试程序会设置为加载此DLL的exe程序。
- 工作目录:通常为调试程序的运行目录,当我们的程序需要使用相对路径的外部资源时就需要使用此参数了,指定一个运行目录。
- 参数:为指定为命名运行的字符串数据。
- 生成后事件:
1:当我们调试DLL工程的时候我们的调试命令通常是exe程序,每次完成编译后我们需要手动将动态库拷贝到exe所在的目录中。
2:通过生成后事件我们可以自动完成拷贝动态库等操作来提高我们的调试效率。
3:拷贝命令示例
a)命令使用的是windows的cmd命令
b)Copy "a.dll" "c:\demo\"
c)Copy "C:\*.dll" "c:\demo\"
3.基本调试方法:
- 启动调试:
- 1、启动,通过点击VS工具栏上的调试按钮,将程序置入调试模式(或者按F5)
- 2、停止,启动调试后通过点击终止按钮来停止调试(或者Shift+F5)
- 3、暂停,如果程序中没有命中断点的情况下程序会顺序的执行代码,在执行过程中我们可以通过暂停按钮来暂时停止代码的执行,程序会停止在当前的执行代码行中。点击运行后又会继续执行。
- 输出窗口的使用:
- 1、当我们启动调试程序之后我们可以使用调试窗口来获取程序的运行信息。
- 2、通过菜单-》视图-》输出,我们则可以打开输出窗口(alt+2)
- 3、启动调试后系统会利用输出窗口反馈程序中所有资源的加载顺序和信息。
- 4、对于有符号DLL,在输出窗口内将会显示,“已加载”,表示挂在DLL对应的符号文件已经完成加载,并观察加载DLL路径是否正确。
- 5、此外输出窗口还可以显示程序调试运行过程中的输出信息。
- 6、我们可以在代码中利用如OutputDebugString这样的API将文本内容输出到输出窗口中显示以便于我们进行调试。
- 断点窗口:
- 1、断点窗口显示程序中加载的所有断点的位置及类型。
- 2、通过菜单-》调试-》窗口-》断点(Alt+F9),可以打开断点窗口,如上图所示。
- 3、我们可以通过断点窗口的工具栏按钮完成以下的操作:
- 删除所有的断点或选定断点
- 禁用启用所有的断点或选中断点,禁用后此断点不会命中
- 导出断点或导入断点
- 4、位置断点的设置:默认情况下我们通过F9键产生的断点类型为位置类型,断点类型为位置类型,即只要代码运行到此位置,即会立即产生命中。
- 5、条件断点的设置
- 条件断点的命中条件可以进行配置,如某一个变量为真,或者等于某一特定的数值时进行命中。我们先产生一个断点,在编辑区左侧断点红色圆形区域点击右键,选择条件断点,选择完毕后,会弹出一个对话框,提示我们输入命中条件。(如右图所示):
- 6、命中次数断点的设置:命中次数断点则可以设置当经过此处固定次数后才进行命中,可供选择的命中次数条件是:总命中,等于某一次数,大于等于某一次数或者几倍于某一次数。(如下图所示)
- 7、筛选器断点的设置:对特定的线程、计算机、进程进行断点
- 8、命中条件断点的设置:命中调试断点可以在命中此断点时输出信息到输出窗口,并且可以直接打印输出变量的数据。
- 9.数据断点设置:运行时断点,只能启动调试并且在暂停条件下才可以进行设置。当指定的内存地址数据发生变化的时候立即进行命中。
-
断点的调试:
- 运行依据代码,遇到函数不进入函数体内部(按F10);跳出当前的函数(按Shift+F11);逐句调试运行,遇到函数调用后进入函数内部继续调试(按F11);在一个堆栈中我们可以通过拖动运行指针来回退代码运行位置。
- 堆栈窗口的使用:
- 1、通过断点我们可以将程序“冻结”在某一个运行时刻,而通过堆栈窗口我们则可以看到程序当前状态的函数调用顺序。
- 2、通过VS的菜单,“调试”-》“窗口”-》“调用堆栈”或者通过Alt+F7打开堆栈窗口
- 3、通过在窗口中双击函数名称我们可以切换到对应的调用函数位置中。(如下图所示:灰色表示无代码和符号不可能已经定位显示)
- 自动变量窗口的使用:
- 自动变量窗口中显示当前堆栈所执行代码行中使用的数据内容,当我们切换到下一行代码后自动变量窗口中的内容会发生对应的变化。
- 局部变量窗口的使用:局部变量窗口显示当前堆栈函数中所使用变量的内容。
- 线程窗口的使用:
- 线程窗口显示当前程序线程的运行状态,在多线程程序开发中我们可以通过这个窗口了解线程的启动和释放情况。每个线程都有自己独立的调用堆栈和变量堆栈,切换不同的线程我们会发现堆栈会发生对应的变化,在线程之前堆数据可以进行共享。黄色箭头表示的是当前代码运行指针所在的线程位置,此外我们还可以看到每个线程所执行的函数体。
- 模块窗口的使用
- 模块窗口显示当前程序所加载的所有模块内容。我们主要通过这个窗口来查看模块是否被正常加载,加载路径是否正确,并判断所需要的模块的符号文件是否已经找到。
- 监视窗口与快速监视窗口的使用
-
在监视窗口中我们可以定义我们所关注的变量,输入变量的内容我们即可获取此变量的内容。变量内容超出当前