首页 > 其他分享 >WinDBG教程

WinDBG教程

时间:2023-04-26 17:36:47浏览次数:43  
标签:教程 WinDBG 显示 命令 堆栈 断点 调试 Windbg



什么是WinDBG?



WinDbg是微软开发的免费源码级调试工具。下载地址为:http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx.

Windbg可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。由于大部分程序员不需要做Kernel模式调试, 我在这篇文章中不会介绍Kernel模式调试。Kernel模式调试对学习Windows核心极有帮助。如果你对此感兴趣,可以阅读Inside Windows 2000和Windbg所带的帮助文件。

 

这篇文章得主要目的是介绍WINDBG的主要功能以及相关的命令。关于这些命令的详细语法,请参阅帮助文件。对文章中提到的许多命令,WINDBG有相应的菜单选项。

如何得到帮助

 

在命令(Command)窗口中输入.hh 命会调出帮助文件令。

 

.hh keyword

会显示关于keyword的详细命令。

 

启动Debugger

 

Windbg可以用于如下三种调试:

 

  1. 远程调试:你可以从机器A上调试在机器B上执行的程序。具体步骤如下:
  •    在机器B上启动一个调试窗口(Debug Session)。你可以直接在Windbg下运行一个程序或者将Windbg附加(Attach)到一个进程。
  • B的Windbg命令窗口上启动一个远程调试接口(remote):

    .server npipe:pipe=PIPE_NAME

     PIPE_NAME是该接口的名字。

  • 在机器A上运行:

windbg –remote npipe:server=SERVER_NAME,pipe=PIPE_NAME

 SERVER_NAME是机器B的名字。

  1. Dump文件调试:如果在你的客户的机器上出现问题,你可能不能使用远程调试来解决问题。你可以要求你的用户将Windbg附加到出现问题的进程上,然后在命令窗口中输入:

.dump /ma File Name

创建一个Dump文件。在得到Dump文件后,使用如下的命令来打开它:

windbg –z DUMP_FILE_NAME

 

  1. 本地进程调试:你可以在Windbg下直接运行一个程序:

Windbg “path to executable” arguments     

    也可以将Windbg附加到一个正在运行的程序:

    Windbg –p “process id”  

Windbg –pn “process name”

    注意有一种非侵入(Noninvasive)模式可以用来检查一个进程的状态并不进程的执行。当然在这种模式下无法控制被调试程序的执行。这种模式也可以用于查看一个已经在Debugger控制下运行的进程。具体命令如下:

    Windbg –pv –p “process id” 

Windbg –pv –pn “process name” 

      

调试多个进程和线程

 

如果你想控制一个进程以及它的子进程的执行,在Windbg的命令行上加上-o选项。Windbg中还有一个新的命令.childdbg 可以用来控制子进程的调试。如果你同时调试几个进程,可以使用 | 命令来显示并切换到不同的进程。

在同一个进程中可能有多个线程。~命令可以用来显示和切换线程。

 

调试前的必备工作

在开始调试前首先要做的工作是设置好符号(Symbols)路径。没有符号,你看到的调用堆栈基本上毫无意义。Microsoft的操作系统符号文件(PDB)是对外公开的。另外请注意在编译你自己的程序选择生成PDB文件的选项。如果设置好符号路径后,调用堆栈看起来还是不对。可以使用lm, !sym noisy, !reload 等命令来验证符号路径是否正确。

 

Windbg也支持源码级的调试。在开始源码调试前,你需要用.srcpath设置源代码路径。如果你是在生成所执行代码的机器上进行调试,符号文件中的源码路径会指向正确的位置,所以不需要设置源代码路径。如果所执行代码是在另一台机器上生成的,你可以将所用的源码拷贝(保持原有的目录结构)的一个可以访问的文件夹(可以是网络路径)并将源代码路径设为该文件夹的路径。注意如果是远程调试,你需要使用.lsrcpath来设置源码路径。

 

静态命令:

显示调用堆栈:在连接到一个调试窗口后,首先要知道的就是程序当前的执行情况k* 命令显示当前线程的堆栈。~*kb会显示所有线程的调用堆栈。如果堆栈太长,Windbg只会显示堆栈的一部分。.kframes可以用来设置缺省显示框架数。

 

显示局部变量:接下来要做通常是用dv显示局部变量的信息。CTRL+ALT+V可以切换到更详细的显示模式。关于dv要注意的是在优化过的代码中dv的输出极有可能是不准确的。这时后你能做的就是阅读汇编代码来发现你感兴趣的值是否存储在寄存器中或堆栈上。有时后当前的框架(Frame)上可能找不到你想知道的数据。如果该数据是作为参数传到当前的方法中的,可以读一读上一个或几个框架的汇编代码,有可能该数据还在堆栈的某个地址上。静态变量是储存在固定地址中的,所以找出静态变量的值较为容易。.Frame(或者在调用堆栈窗口中双击)可以用来切换当前的框架。注意dv命令显示的是当前框架的内容。你也可在watch窗口中观察局部变量的值。

 

显示类和链表dt可以显示数据结构。比如dt PEB 会显示操作系统进程结构。在后面跟上一个进程结构的地址会显示该结构的详细信息:dt PEB 7ffdf000

Dl命令可以显示一些特定的链表结构。

 

显示当前线程的错误值!gle会显示当前线程的上一个错误值和状态值。!error命令可以解码HRESULT。

 

搜索或修改内存:使用s 命令来搜索字节,字或双字,QWORD或字符串。使用e命令来修改内存。

 

计算表达式:?命令可以用来进行计算。关于表达式的格式请参照帮助文档。使用n命令来切换输入数字的进制。

 

显示当前线程,进程和模块信息!teb显示当前线程的环境信息。最常见的用途是查看当前线程堆栈的起始地址,然后在堆栈中搜索值。!peb显示当前进程的环境信息,比如执行文件的路径等等。lm显示进程中加载的模块信息。

 

 

显示寄存器的值r命令可以显示和修改寄存器的值。如果要在表达式中使用寄存器的值,在寄存器名前加@符号(比如@eax)。

 

 

显示最相近的符号ln Address。如果你有一个C++对象的指针,可以用来ln来查看该对象类型。

 

查找符号x命令可以用来查找全局变量的地址或过程的地址。x命令支持匹配符号。x kernel32!*显示Kernel32.dll中的所有可见变量,数据结构和过程。

 

 

查看lock:!locks显示各线程的锁资源使用情况。对调试死锁很有用。

 

查看handle:!handle显示句柄信息。如果一段代码导致句柄泄漏,你只需要在代码执行前后使用!handle命令并比较两次输出的区别。有一个命令!htrace对调试与句柄有关的Bug非常有用。在开始调试前输入:

!htrace –enable

然后在调试过程中使用!htrace handle_value 来显示所有与该句柄有关的调用堆栈。

 

显示汇编代码u

 

程序执行控制命令:

设置代码断点bp/bu/bm 可以用来设置代码断点。你可以指定断点被跳过的次数。假设一段代码KERNEL32!SetLastError在运行很多次后会出错,你可以设置如下断点:

    bp KERNEL32!SetLastError 0x100.

在出错后使用bl 来显示断点信息(注意粗体显示的值):

0 e 77e7a3b0     004f (0100)  0:*** KERNEL32!SetLastError

重新启动调试(.restart命令)并设置如下的断点:

bp Kernel32!SetLastError 0x100-0x4f

Debugger会停在出错前最后一次调用该过程的地方。

 

你可以指定断点被激活时Debugger应当执行的命令串。在该命令串中使用J命令可以用来设置条件断点:

bp `mysource.cpp:143` "j (poi(MyVar)”0n20) ''; 'g' "

上面的断点只在MyVar的值大于32时被激活(g命令

 

条件断点的用途极为广泛。你可以指定一个断点只在特殊的情况下被激活,比如传入的参数满足一定的条件,调用者是某个特殊的过程,某个全局变量被设为特殊的值等等。

 

设置内存断点:ba可以用来设置内存断点。调试过程中一个常见的问题是跟踪某些数据的变化。如下的断点:

ba w4 0x40000000 "kb; g"

可以打印出所有修改0x40000000的调用堆栈。

 

控制程序执行p, pa,t, ta等命令可以用来控制程序的执行。

 

控制异常和事件处理:Debugger的缺省设置是跳过首次异常(first chance expcetion),在二次异常(second chance exception)时中断程序的执行。sx命令显示Debugger的设置。sxesxd可以改变Debugger的设置。

    sxe clr

可以控制Debugger在托管异常发生时中断程序的执行。常用的Debugger事件有:

    av    访问异常 

     eh    C++异常

    clr   托管异常

    ld    模块加载

-c 选项可以用来指定在事件发生时执行的调试命令。

标签:教程,WinDBG,显示,命令,堆栈,断点,调试,Windbg
From: https://blog.51cto.com/u_130277/6228203

相关文章

  • 全网最详细的Python安装教程
    https://zhuanlan.zhihu.com/p/569019068 1.首先打开下载配置环境  https://www.python.org/downloads/windows/ 2.64位操作系统:找到windowsx86-64executableinstaller并点击,耐心等待下载完成!3.安装python4.2-1下载完后双击点开python-3.7.4.exe 下面两个都 ......
  • Java8 Lambda表达式教程
    1.什么是λ表达式 λ表达式本质上是一个匿名方法。让我们来看下面这个例子:   publicintadd(intx,inty){       returnx+y;   }转成λ表达式后是这个样子:       (intx,inty)->x+y;参数类型也可以省略,Java编译器会根据上下文推断出来:  ......
  • rockyLinux 初体验(教程)PostgreSQL15
    目录数据库软件PostgreSQL安装数据库软件PostgreSQL配置数据库软件PostgreSQL交互通用数据库管理软件DBeaver彼时,PostgreSQL已经更新到了15.2。距离我上一次写PostgreSQL教程2022-03-20,已经过去一年多了。Linux篇PostgreSQL教程很久之前就想写了,一直停留在想法上......
  • Three.js教程:顶点索引复用顶点数据
    推荐:将NSDT场景编辑器加入你3D工具链其他工具系列:NSDT简石数字孪生顶点索引复用顶点数据通过几何体BufferGeometry的顶点索引属性BufferGeometry.index可以设置几何体顶点索引数据,如果你有WebGL基础很容易理解顶点索引的概念,如果没有也没有关系,下面会通过一个简单的例子形象说......
  • 动力节点老杜Vue框架教程【三】Vue组件化
    Vue.js是一个渐进式MVVM框架,目前被广泛使用,也成为前端中最火爆的框架Vue可以按照实际需要逐步进阶使用更多特性,也是前端的必备技能动力节点老杜的Vue2+3全家桶教程已经上线咯!学习地址:https://www.bilibili.com/video/BV17h41137i4/视频将从Vue2开始讲解,一步一个案例,知识点......
  • Yuzuki Lizard 全志V851S开发板 –移植 QT5.12.9教程
    移植QT5教程(此教程基于docker版V851S开发环境)dockerpullregistry.cn-hangzhou.aliyuncs.com/gloomyghost/yuzukilizard编译依赖apt-getinstallrepogitgcc-arm-linux-gnueabihfu-boot-toolsdevice-tree-compilermtools\partedlibudev-devlibusb-1.0-0-devpython......
  • 动力节点老杜Vue框架教程【三】Vue组件化
    Vue.js是一个渐进式MVVM框架,目前被广泛使用,也成为前端中最火爆的框架Vue可以按照实际需要逐步进阶使用更多特性,也是前端的必备技能动力节点老杜的Vue2+3全家桶教程已经上线咯!学习地址:https://www.bilibili.com/video/BV17h41137i4/视频将从Vue2开始讲解,一步一个案例,知识点由浅入......
  • Java8 教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介Java8(又称为jdk1.8)是Java语言开发的一个主要版本。Java8是oracle公司于2014年3月发布,可以看成是自Java5以来最具革命性的版本。Java8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性。Java8入门教程-从简单的步骤了解Java8,从基本到高级概......
  • ant-design blazor 简单使用教程
    使用教程  先本地安装模板,然后再创建项目例:dotnetnew--installAntDesign.Templates dotnetnewantdesign--host=wasm--full-omonitor生成后的项目如图所示: 直接运行,就可以看到结果了,开发效率确实很高,适用于小型项目,比如监控面板这种内部用,又没有多少开发资......
  • 【NLP教程】用python调用百度AI开放平台进行情感倾向分析
    目录一、背景二、操作步骤2.1创建应用2.2获取token2.3情感倾向分析三、其他情感分析四、讲解视频一、背景Hi,大家!我是@马哥python说,一名10年程序猿。今天我来演示一下:通过百度AI开放平台,利用python调用百度接口进行中文情感倾向分析,并得出情感极性分为积极、消极还是中性以......