分类 调试 下的文章

如果用户模式应用程序已经在运行,调试器可以非侵入性地对其进行调试。对于非侵入性调试,您没有那么多的调试操作。但是,您可以最小化调试器对目标应用程序的干扰。如果目标应用程序已停止响应,则非侵入性调试非常有用。
在非侵入性调试中,调试器实际上并不附加到目标应用程序。调试器挂起目标的所有线程,并可以访问目标的内存、寄存器和其他此类信息。但是,调试器无法控制目标,因此g(Go)等命令不起作用。
如果尝试执行非侵入性调试期间不允许的命令,则会收到一条错误消息,指出“The debugger is not attached, so process execution cannot be monitored.(未附加调试器,因此无法监视进程执行。)”

选择要调试的进程

您可以通过进程ID(PID)或进程名指定目标应用程序。如果按名称指定应用程序,则应使用进程的完整名称,包括文件扩展名。如果两个进程具有相同的名称,则必须改用进程ID。

通过WinDbg命令行

要从WinDbg命令行无创地调试正在运行的进程,请使用以下语法指定-pv选项、-p选项和进程ID。

windbg -pv -p ProcessID

或者,要通过指定进程名来无创地调试正在运行的进程,请改用以下语法。

windbg -pv -pn ProcessName

通过WinDbg菜单

当WinDbg处于休眠模式时,通过单击“文件”菜单上的“附加到进程”或按F6键,可以无创地调试正在运行的进程。出现“附加到进程”对话框时,选中“非侵入性”复选框。然后,选择包含所需进程ID和名称的行。(也可以在“进程ID”框中输入进程ID。)最后,单击“确定”。

当我们启动windbg后,我们就能看到Windbg的样子了,如下:

本部分讨论 WinDbg 图形用户界面的元素。 这些元素包括以下各项:菜单、工具栏和快捷键。菜单有:文件菜单、编辑菜单、视图菜单、调试菜单、窗口菜单、帮助菜单。下面分别一 一简单介绍下。

一、菜单

1.1、文件菜单

  • 打开源文件
    加载特定的源文件。此命令相当于按 CTRL + O 或单击开放源代码文件 (Ctrl + O) 按钮 (开放源代码文件按钮的屏幕截图)。

    当您单击打开源文件,则打开源文件对话框随即出现。 若要打开一个文件,请执行以下操作:


    1. 在中查找列表中,选择该文件所在的目录。 默认情况下,选择上一次打开的目录。

    2. 在中类型的文件列表中,选择你想要打开的文件的类型。 仅使用所选扩展的文件将显示在打开源文件对话框。 请注意  还可以使用中的通配符模式文件名框,以显示仅具有特定扩展名的文件。 在更改之前的会话中保留新的通配符模式。 可以使用通配符模式,之间用分号分隔的任意组合。 例如,输入 *。非独占;*.H;*.CPP显示具有这些扩展名的所有文件。 最大的行中的字符数为 251。

    3. 如果找到该文件所需,双击文件名称,或单击文件名称并单击打开。若要放弃更改并关闭对话框,请单击取消。

    当你指向时显示在 WinDbg 中最近打开的四个文件的名称最近使用的文件上文件菜单。 若要打开这些文件之一,请单击其名称。
  • 关闭当前窗口

    单击关闭当前窗口上文件菜单关闭的活动的调试信息窗口。此命令相当于按下 CTRL + F4。此外可以通过单击关闭调试的信息窗口关闭在 WinDbg 窗口中信息窗口的右上角的按钮。

  • 打开可执行文件

    单击打开可执行文件上文件菜单以启动新的用户模式进程,并对其进行调试。此命令相当于按下 CTRL + E。 仅当 WinDbg 处于休眠模式时,可以使用此命令。

    当您单击打开可执行文件,则打开可执行文件对话框随即显示,并且您可以执行以下操作:


    • 输入中的可执行文件的完整路径文件名框。 或者,可以使用对话框的查找并选择适当的文件。 必须指定可执行文件的确切路径。 与 Microsoft Windows 不同运行对话框和命令提示符窗口,打开可执行对话框不会搜索当前路径的可执行文件的名称。

    • 如果你想要使用的可执行文件使用命令行参数,输入中对其自变量框。

    • 如果你想要更改的开始目录从默认目录中输入该目录路径开始目录框。

    • 如果你想要附加到任何的 WinDbg子进程(其他进程的原始目标进程启动),选择调试子进程也。


    进行选择后,单击打开。

    请注意  时使用此命令以打开源文件,该文件的路径自动追加到源路径。

    如果 WinDbg 连接到进程服务器,则无法使用打开可执行文件命令。

  • 附加到进程

    单击附加到进程上文件菜单调试当前正在运行的用户模式应用程序。此命令相当于按 F6。 仅当 WinDbg 处于休眠模式时,可以使用此命令。

    当您单击附加到进程,则附加到进程对话框随即显示,并且您可以执行以下操作:


    • 选择包含正确的进程 ID 和名称的行 (或输入中的进程 ID进程 ID框)。 请注意  列出的每个进程具有关联的加号 (+)。 可以单击加号以显示有关该进程的命令行、 服务和子进程的信息。

      请注意  如果 WinDbg 连接到进程服务器附加到进程对话框将显示在远程计算机运行的进程。 进程服务器的详细信息,请参阅激活智能客户端。

    • 如果你想要 noninvasively(非侵入) 附加到进程,请选择Noninvasive复选框。


    进行选择后,单击确定。

  •  打开故障转储文件

    单击打开故障转储文件菜单以打开用户模式或内核模式崩溃转储文件,并对其进行分析。此命令相当于按下 CTRL + D。 仅当 WinDbg 处于休眠模式时,可以使用此命令。

    当您单击打开崩溃转储,则打开崩溃转储对话框随即出现。 输入中的故障转储文件的完整路径文件名框中,或使用查找列表以查找并选择正确的路径和文件名称。 (转储文件通常具有.dmp 或.mdmp 扩展名结尾)。

    选择适当的文件后,单击打开。

  • 连接到远程会话

    单击连接到远程会话上文件菜单使 WinDbg 调试客户端并连接到活动的调试服务器。此命令相当于按下 CTRL + R。 仅当 WinDbg 处于休眠模式时,可以使用此命令。不能使用此命令连接到进程服务器或 KD 连接服务器。为此,使用文件 |连接到远程存根 (stub)相反。

    当您单击连接到远程会话,则连接到远程调试器会话对话框随即出现。 可以使用此对话框中,输入远程连接参数,或若要浏览的调试服务器列表。

    若要手动指定远程连接参数,请输入中的以下字符串之一连接字符串框:

    text

硬件断点的原理

Intel 80306以上的CPU给我们提供了调试寄存器用于软件调试,硬件断点是通过设置调试寄存器实现的。

 

上图为Intel手册提供的32位操作系统下8个调试寄存器的图示(Intel手册卷3 17章第二节 Debug Registers,有兴趣的朋友可以查阅),根据介绍,DR0-DR3为设置断点的地址,DR4和DR5为保留,DR6为调试异常产生后显示的一些信息,DR7保存了断点是否启用、断点类型和长度等信息。

我们在使用硬件断点的时候,就是要设置调试寄存器,将断点的位置设置到DR0-DR3中,断点的长度设置到DR7的LEN0-LEN3中,将断点的类型设置到DR7的RW0-RW3中,将是否启用断点设置到DR7的L0-L3中。设置硬件断点需要的DR0-DR3很简单,就是下断点的地址,DR7寄存器很复杂,位段信息结构体如下:

typedef struct_DBG_REG7
{
/*// 局部断点(L0~3)与全局断点(G0~3)的标记位*/unsigned L0 :1; //对Dr0保存的地址启用 局部断点 unsigned G0 : 1; //对Dr0保存的地址启用 全局断点 unsigned L1 : 1; //对Dr1保存的地址启用 局部断点 unsigned G1 : 1; //对Dr1保存的地址启用 全局断点 unsigned L2 : 1; //对Dr2保存的地址启用 局部断点 unsigned G2 : 1; //对Dr2保存的地址启用 全局断点 unsigned L3 : 1; //对Dr3保存的地址启用 局部断点 unsigned G3 : 1; //对Dr3保存的地址启用 全局断点 /*// 【以弃用】用于降低CPU频率,以方便准确检测断点异常*/unsigned LE :1;
unsigned GE :
1;/*// 保留字段*/unsigned Reserve1 :3;/*// 保护调试寄存器标志位,如果此位为1,则有指令修改条是寄存器时会触发异常*/unsigned GD :1;/*// 保留字段*/unsigned Reserve2 :2;

unsigned RW0 :
2; //设定Dr0指向地址的断点类型 unsigned LEN0 : 2; //设定Dr0指向地址的断点长度 unsigned RW1 : 2; //设定Dr1指向地址的断点类型 unsigned LEN1 : 2; //设定Dr1指向地址的断点长度 unsigned RW2 : 2; //设定Dr2指向地址的断点类型 unsigned LEN2 : 2; //设定Dr2指向地址的断点长度 unsigned RW3 : 2; //设定Dr3指向地址的断点类型 unsigned LEN3 : 2; //设定Dr3指向地址的断点长度 }DBG_REG7, *PDBG_REG7;

一、WinDbg简介

WinDbg是微软发布的一款免费而十分强大的调试工具。既然是微软自己发布的调试工具,那它对微软产品的调试当然是十分的强大。Windows 调试器 (WinDbg) 可用于调试内核模式和用户模式代码,来分析故障转储,并检查代码时 CPU 寄存器执行,同时也是一款相当优秀的源码级(source-level)调试工具。相比较于Visual Studio,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为强大。

二、获取和安装

2.1、获取途径

可以将Windows调试工具作为开发工具包的一部分或作为独立工具集获取:

  • 作为WDK的一部分
    Windows的调试工具包含在Windows驱动程序工具包(WDK)中。Download the Windows Driver Kit (WDK).
  • 作为Windows SDK的一部分
    Windows软件开发工具包(SDK)中包含Windows调试工具。要下载安装程序或ISO映像,请参阅Windows开发人员中心上的Windows 10 SDK
  • 作为独立的工具集
    通过开始安装Windows SDK,然后在要安装的功能列表中仅选择Windows的调试工具(并清除所有其他功能的选择),可以在不安装Windows SDK或WDK的情况下单独安装Windows的调试工具。要下载安装程序或ISO映像,请参阅Windows开发人员中心上的Windows 10 SDK

2.2、安装

安装过程略

下面是安装后的截图

作为独立工具集安装后

作为SDK一部分安装后

启动后的界面

三、配置

安装好之后就需要配环境变量,打开环境变量配置界面 我的电脑->右键属性->高级系统设置->环境变量设置->在系统变量里找到path,把你的WinDbg安装目录写上去

设置好后,在命令行里输入windbg,如果能跑起来,则设置成功,然后再在系统变量中创建一个名为 _NT_SYMBOL_PATH,值为:SRV*F:\Debug_Symbol\Symbols32* http://msdl.microsoft.com/download/symbols

启动Windbg 打开一个exe看到这个说明配置成功

 

四、功能

Windbg是Microsoft公司免费调试器调试集合中的GUI的调试器,支持Source和Assembly两种模式的调试。Windbg不仅可以调试应用程序,还可以进行Kernel Debug。结合Microsoft的Symbol Server,可以获取系统符号文件,便于应用程序和内核的调试。Windbg支持的平台包括X86、IA64、AMD64。虽然windbg也提供图形界面操作,但它最强大的地方还是有着强大的调试命令,一般情况会结合GUI和命令行进行操作,常用的视图有:局部变量、全局变量、调用栈、线程、命令、寄存器、白板等。其中“命令”视图是默认打开的。

低层次思考,我指的是从应用程序内部思考的重要性,有时是在机器代码级别。

大多数人认为,要知道如何调试应用程序,只需要学习如何使用调试器。但事实上,学习如何使用调试器只是解决复杂软件问题所需的一部分。因此,我觉得有必要解释在处理应用程序问题(如挂起、崩溃、内存泄漏、应用程序错误和性能问题)时,低层思考是多么重要。