目录
调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令
首页 数据库 mysql教程 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

Jun 07, 2016 pm 03:26 PM
sqlserver WinDbg 使用 命令 调试

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令 调试SQLSERVER (一)生成dump文件的方法 调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置 windbg命令分为 标准命令、 元命令、 扩展命令 标准命令提供最基本的调试功能,不区分大小写。如:

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

调试SQLSERVER (一)生成dump文件的方法
调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置

 

windbg命令分为标准命令、元命令、扩展命令

标准命令提供最基本的调试功能,不区分大小写。如:bp g dt dv k等

元命令提供标准命令没有提供的功能,也内建在调试引擎中,以.开头。如.sympath .reload等

扩展命令用于扩展某一方面的调试功能,实现在动态加载的扩展模块中,以!开头。如!analyze等

 

下面我们会直接将debugger 附加到sqlservr.exe 进程

在附加sqlservr之前,我们需要获得SQLSERVER的PID,在第一篇的时候我们就说过如何获取SQLSERVER的PID,我们这里就不再叙述了

GO OVER 回顾:调试SQLSERVER (一)生成dump文件的方法

 

注意:附加debugger 到sqlserver进程会停止SQLSERVER的运行,不要在生产环境上乱试!!

 

在调试的时候你可以在命令框里输入一些命令

首先,一个 stack trace很明显是对应一个线程的,SQLSERVER是一个多线程应用程序,要获得sqlserver的线程列表,使用命令:~

使用Windbg版本:6.12.0002.633 AMD64

SQL版本:SQL2008R2

操作系统:WIN2008R2

我们附加SQL进程

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 SQL进程ID是6192

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

如果要退出,记得输入q命令,而不要直接关闭窗口,要分离调试而不关闭命令行界面,输入.detach命令

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

.detach <span>//</span><span> 分离调试

.restart </span><span>//</span><span> 重启并调试

.</span><span>kill</span> <span>//</span><span> 强制结束当前调试

q </span><span>//</span> 结束被调试进程,关闭命令行界面,返回到最初的工作空间

 

 

附加成功了,我们看到Windbg会加载一些必要的模块

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 

然后,我们输入 ~  命令看一下当前SQL进程的线程列表

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

进程环境块(Process Enviroment Block)Peb

线程环境块(Thread Enviroment Block)Teb

Peb和Teb都是Windows的内核结构体,对于我们来说可以不用深入研究,毕竟我们不是专业的

当然有些可以查看Peb和Teb的命令在本文也不会进行介绍

 

在调试期间,是没有办法连接SQLSERVER的,连接的时候会报错

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

并且,如果你当前正在执行SQL语句,也会hang住

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

再说一次:附加debugger 到sqlserver进程会停止SQLSERVER的运行,不要在生产环境上乱试!!

 

 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

从上图中可以看到我们有47个线程 ,线程从0开始计数。

 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

在左边边缘的句点指明当前正在上下文中(in context)运行的线程,在提示框中(0:046>)也指明了当前上下文的线程的序数是46

第一列的数字只是给调试器使用的数字序数列

 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

接下来那一列才是进程:线程列,调试器以hex的形式来显示(pid.tid),比如上面的46  Id: 1830.18a8 Suspend:1

1830的十进制是6192,18a8的十进制是6312

那么  Id: 1830.18a8就表示进程id是6192:线程id是6312

tid:thread id

 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

我们假设有一个查询正在运行在线程36上面(9e4),我想看一下这个线程的stack trace。

我们可以发出相关命令来查看stack trace,命令是k,k命令可以附带有多个参数,

例如:

提供函数参数  输入  kv 

提供frame 号码 输入  kn 

提供内存使用 输入  kf 

我们现在只关注k命令,我们可以对这个线程设置上下文或查看

要设置上下文,可以使用命令 <span>~</span>36s ,s说明提取线程~36并设置我们的上下文(s)

当我们身处另外一个线程的上下文的时候,如果我们只是需要查看一下这个36线程的 stack trace,我们可以使用命令: ~36k 

现在我们设置我们的上下文并获取我们的stack trace

使用命令:

<span>~</span>36s

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

然后输入命令 : k  

注意:设置符号路径的时候,在符号文件夹下面一定要有sqlservr.pdb文件夹,否则当输入k命令的时候,会得不到函数名

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

下面是没有设置正确的符号路径和设置正确的符号路径的对比

设置正确,能看到实际的函数名

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

设置不正确,看不到实际的函数名

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 

大家可以对比一下 <span>~</span>36s 命令和 k  命令

先用 <span>~</span>36s  命令切换到36线程的上下文,并显示出当前36线程所执行的函数

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

然后用 k  命令进一步显示36线程的上下文内容,调用层次

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 比如我们输入  kf 查看一下各个函数的内存使用也是可以的,显示内存的单位是byte

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

输入 kn  加上frame号码

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

好了,回到刚才那里,我们现在在36线程的上下文里,最顶端的函数是“ntdll!NtSignalAndWaitForSingleObject” ,也是正在执行和最后执行的函数

这里其实是一个Windows API将我们的线程带入等待状态--等待线程需要的东西准备好的一个信号。

这里的Child-SP(Stack Pointer)和RetAddr(Return Address) ,他们是用于明确栈帧的构造和用于当前函数完成的时候返回执行结果

 

当我们需要知道当前sqlserver版本的时候,我们可以使用命令 lm

当然,这个命令也是有很多附带参数的,我们使用下面命令获得sqlservr模块的具体信息

lmvm sqlservr

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

有时候,lm命令对于微软的技术支持来说是很重要的,因为从这个命令的运行结果可以知道客户使用的操作系统版本,SQLSERVER版本

SQLSERVER是32位还是64位,是SQL2008还是SQL2008R2

如果输入  lm 命令, 就可以得到SQLSERVER地址空间里所加载的模块列表

deferred:表示延迟加载

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 

 

如果要验证调试器所加载的目标,我们可以使用管道命令: |  

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

 

 

内存命令

我们有时候可能还想把进程的内存内容dump出来,那么我们可以使用 d命令,d命令也一样有很多的附带参数,

例如

dc:把提供的地址处内存转换为ASCII字符数据

dd:只显示 4字节DWORD格式 

内存命令一般用于分析堆空间的内存,或者栈内存里所传递的参数数据

 

我们看一下10号线程的栈情况

<span>**</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\SYSTEM32\ntdll.dll <span>-</span> 
<span>0</span>:<span>010</span><span>></span> <span>~</span><span>10s
</span><span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\system32\KERNELBASE.dll <span>-</span><span> 
ntdll!NtWaitForSingleObject</span><span>+</span><span>0xa</span><span>:
</span><span>00000000</span><span>`774412fa c3              ret
</span><span>0</span>:<span>010</span><span>></span><span> k
Child</span><span>-</span><span>SP          RetAddr           Call Site
</span><span>00000000</span>`079deb98 000007fe`fd2110dc ntdll!NtWaitForSingleObject<span>+</span><span>0xa</span>
<span>00000000</span>`079deba0 <span>00000000</span>`00d83b55 KERNELBASE!WaitForSingleObjectEx<span>+</span><span>0x9c</span>
<span>00000000</span>`079dec40 <span>00000000</span>`00d834ca sqlservr!SOS_Scheduler::SwitchContext<span>+</span><span>0x26d</span>
<span>00000000</span>`079df0d0 <span>00000000</span>`00d82710 sqlservr!SOS_Scheduler::SuspendNonPreemptive<span>+</span><span>0xca</span>
<span>00000000</span>`079df110 <span>00000000</span>`00d829bc sqlservr!SOS_Scheduler::Suspend<span>+</span><span>0x2d</span>
<span>00000000</span>`079df140 <span>00000000</span>`00da2eab sqlservr!EventInternal<span><</span>Spinlock<span><</span><span>154</span>,<span>1</span>,<span>0</span><span>></span> <span>></span>::Wait<span>+</span><span>0x1a8</span>
<span>00000000</span>`079df190 <span>00000000</span>`<span>01949951</span> sqlservr!CTraceManagementTask::Invoke<span>+</span><span>0xbe</span>
<span>00000000</span>`079df1f0 <span>00000000</span>`00d8eb40 sqlservr!CTraceBatchTask::Task<span>+</span><span>0x1ad</span>
<span>00000000</span>`079df2d0 <span>00000000</span>`00d8f15a sqlservr!SOS_Task::Param::<span>Execute</span><span>+</span><span>0x12a</span>
<span>00000000</span>`079df3e0 <span>00000000</span>`00d8ef9f sqlservr!SOS_Scheduler::RunTask<span>+</span><span>0x96</span>
<span>00000000</span>`079df440 <span>00000000</span>`0135e8ee sqlservr!SOS_Scheduler::ProcessTasks<span>+</span><span>0x128</span>
<span>00000000</span>`079df4b0 <span>00000000</span>`0135eb25 sqlservr!SchedulerManager::WorkerEntryPoint<span>+</span><span>0x2d2</span>
<span>00000000</span>`079df590 <span>00000000</span>`00ea7631 sqlservr!SystemThread::RunWorker<span>+</span><span>0xcc</span>
<span>00000000</span>`079df5d0 <span>00000000</span>`0135f67a sqlservr!SystemThreadDispatcher::ProcessWorker<span>+</span><span>0x2db</span>
<span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.<span>0.50727</span>.4940_none_88df89932faf0bf6\MSVCR80.dll <span>-</span> 
<span>00000000</span>`079df680 <span>00000000</span>`74c437d7 sqlservr!SchedulerManager::ThreadEntryPoint<span>+</span><span>0x173</span>
<span>00000000</span>`079df720 <span>00000000</span>`74c43894 MSVCR80!endthreadex<span>+</span><span>0x47</span>
<span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\system32\kernel32.dll <span>-</span> 
<span>00000000</span>`079df750 <span>00000000</span>`771e59ed MSVCR80!endthreadex<span>+</span><span>0x104</span>
<span>00000000</span>`079df780 <span>00000000</span>`7741c541 kernel32!BaseThreadInitThunk<span>+</span><span>0xd</span>
<span>00000000</span>`079df7b0 <span>00000000</span>`<span>00000000</span> ntdll!RtlUserThreadStart<span>+</span><span>0x21</span>

<span>0</span>:<span>010</span><span>></span> dc <span>00000000</span><span>`079df4b0
</span><span>00000000</span>`079df4b0  <span>00000000</span> <span>00000000</span> 804aa1a0 <span>00000000</span><span>  ..........J.....
</span><span>00000000</span>`079df4c0  fff914a8 000007ff <span>00000000</span> <span>00000000</span><span>  ................
</span><span>00000000</span>`079df4d0  8fe8cfb8 00002<span>dec</span> <span>00000000</span> <span>00000000</span>  .....<span>-</span><span>..........
</span><span>00000000</span>`079df4e0  032af070 <span>00000000</span> <span>00000000</span> <span>00000000</span>  p.<span>*</span><span>.............
</span><span>00000000</span>`079df4f0  08d80080 <span>00000000</span> <span>00000000</span> <span>00000000</span><span>  ................
</span><span>00000000</span>`079df500  <span>00000001</span> <span>00000000</span><span> fff914a8 000007ff  ................
</span><span>00000000</span>`079df510  <span>00000006</span> <span>00000000</span><span> fffffffe ffffffff  ................
</span><span>00000000</span><span>`079df520  fff914a8 000007ff fff9155c 000007ff  ........\.......
</span><span>0</span>:<span>010</span><span>></span><span> dc
</span><span>00000000</span>`079df530  804aa1a0 <span>00000000</span><span> fff90000 000007ff  ..J.............
</span><span>00000000</span>`079df540  271516fd <span>00000000</span> fffffffe ffffffff  ...<span>'</span><span>............
00000000`079df550  00000003 00000000 fd210000 000007fe  ..........!.....
00000000`079df560  8fe8ce78 00002dec 00000000 00000000  x....-..........
00000000`079df570  804aa1a0 00000000 fff914a8 000007ff  ..J.............
00000000`079df580  00000000 00000000 0135eb25 00000000  ........%.5.....
00000000`079df590  804aa1a0 00000000 ab0c671e 00000d5f  ..J......g.._...
00000000`079df5a0  ab0c6720 00000d5f ab0c6723 00000d5f   g.._...#g.._...</span>

我们首先切到10号线程 (~10s),然后显示stack (k)。最后我们取出其中一个栈(在stack trace里面的一行),

然后利用Child-SP来dump 出来内存地址,Child-SP在stack-trace里面是一个栈帧的指针---指向栈帧在内存中的起始地址

 

 

目前我们只是介绍了在调试里面的一些普通的命令

我们会接着介绍下面命令

<span>vertarget
.chain
!analyze
x
r
u
bp, bl, bc</span>

 

 

vertarget命令

查看目标系统的版本信息,可使用下面的vertarget命令,vertarget命令给出在目标机器上的OS版本或者机器运行时间

<span>0</span>:<span>010</span><span>></span><span> vertarget
Windows </span><span>7</span> Version <span>7601</span> (Service Pack <span>1</span>) MP (<span>2</span><span> procs) Free x64
Product: Server, suite: TerminalServer DataCenter SingleUserTS
kernel32.dll version: </span><span>6.1</span>.<span>7601.18409</span> (win7sp1_gdr.<span>140303</span><span>-</span><span>2144</span><span>)
Machine Name:
Debug session time: Fri </span><span>Dec</span> <span>26</span> <span>12</span>:<span>04</span>:<span>42.159</span> <span>2014</span> (UTC <span>+</span> <span>8</span>:<span>00</span><span>)
System Uptime: </span><span>17</span> days <span>2</span>:<span>05</span>:<span>00.191</span><span>
Process Uptime: </span><span>0</span> days <span>1</span>:<span>37</span>:<span>28.844</span><span>
  Kernel time: </span><span>0</span> days <span>0</span>:<span>00</span>:<span>00.109</span>
  <span>User</span> time: <span>0</span> days <span>0</span>:<span>00</span>:<span>00.437</span>

 

 

.chain命令

能够给出一个扩展命令集的链表,大家看到.chain是有.开头,所以他是元命令

<span>0</span>:<span>010</span><span>></span><span> .chain
Extension DLL search Path:
    C:\Program Files\Debugging Tools </span><span>for</span> Windows (x64)\WINXP;C:\Program Files\Debugging Tools <span>for</span> Windows (x64)\winext;C:\Program Files\Debugging Tools <span>for</span> Windows (x64)\winext\arcade;C:\Program Files\Debugging Tools <span>for</span> Windows (x64)\pri;C:\Program Files\Debugging Tools <span>for</span> Windows (x64);C:\Program Files\Debugging Tools <span>for</span> Windows (x64)\winext\arcade;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.<span>0</span>\;C:\Program Files (x86)\Microsoft SQL Server\<span>100</span>\Tools\Binn\;C:\Program Files\Microsoft SQL Server\<span>100</span>\Tools\Binn\;C:\Program Files\Microsoft SQL Server\<span>100</span>\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\<span>100</span>\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio <span>9.0</span>\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SQL Server\<span>100</span>\DTS\Binn\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.<span>0</span><span>\;C:\Program Files\Microsoft Windows Performance Toolkit\
Extension DLL chain:
    dbghelp: </span><span>image</span> <span>6.12</span>.<span>0002.633</span>, API <span>6.1</span>.<span>6</span>, built Tue Feb <span>02</span> <span>04</span>:<span>15</span>:<span>44</span> <span>2010</span>
        <span>[</span><span>path: C:\Program Files\Debugging Tools for Windows (x64)\dbghelp.dll</span><span>]</span><span>
    ext: </span><span>image</span> <span>6.12</span>.<span>0002.633</span>, API <span>1.0</span>.<span>0</span>, built Tue Feb <span>02</span> <span>04</span>:<span>15</span>:<span>46</span> <span>2010</span>
        <span>[</span><span>path: C:\Program Files\Debugging Tools for Windows (x64)\winext\ext.dll</span><span>]</span><span>
    exts: </span><span>image</span> <span>6.12</span>.<span>0002.633</span>, API <span>1.0</span>.<span>0</span>, built Tue Feb <span>02</span> <span>04</span>:<span>15</span>:<span>38</span> <span>2010</span>
        <span>[</span><span>path: C:\Program Files\Debugging Tools for Windows (x64)\WINXP\exts.dll</span><span>]</span><span>
    uext: </span><span>image</span> <span>6.12</span>.<span>0002.633</span>, API <span>1.0</span>.<span>0</span>, built Tue Feb <span>02</span> <span>04</span>:<span>15</span>:<span>36</span> <span>2010</span>
        <span>[</span><span>path: C:\Program Files\Debugging Tools for Windows (x64)\winext\uext.dll</span><span>]</span><span>
    ntsdexts: </span><span>image</span> <span>6.1</span>.<span>7650.0</span>, API <span>1.0</span>.<span>0</span>, built Tue Feb <span>02</span> <span>04</span>:<span>15</span>:<span>18</span> <span>2010</span>
        <span>[</span><span>path: C:\Program Files\Debugging Tools for Windows (x64)\WINXP\ntsdexts.dll</span><span>]</span>

最上面两行显示了扩展模块的搜索路径。

接下来共列出了5个Windbg自带的扩展模块:dbghellp、ext、exts、uext和ntsdexts。可以查看到这些扩展模块的版本信息、镜像文件路径。

 

 

!analyze -v

详细显示当前异常信息,!analyze是一个扩展命令,

此命令分析当前最近的异常事件(如果在进行dump分析,则是bug check),并显示分析结果

参数

-v:显示异常的详细信息,这个选项在调试错误的时候最有用。
-f:f是force的缩写。强制将任何事件都当作异常来分析,即使仅仅是普通的断点事件。将因此多输出一些内容。
-hang:在内核环境中,它分析内核锁和DPC栈;在用户环境中,它分析线程的调用栈,调试器只会对当前线程进行分析,所以一定要将线程环境切换到最可能引起问题的那个线程中去才有帮助。

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

<span>0</span>:<span>010</span><span>></span> !analyze <span>-</span><span>v
</span><span>*******************************************************************************</span>
<span>*</span>                                                                             <span>*</span>
<span>*</span>                        Exception Analysis                                   <span>*</span>
<span>*</span>                                                                             <span>*</span>
<span>*******************************************************************************</span>

<span>*****</span> OS symbols are WRONG. Please fix symbols <span>to</span><span> do analysis.

</span><span>*************************************************************************</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Your debugger <span>is</span> <span>not</span> using the correct symbols                 <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    <span>In</span> <span>order</span> <span>for</span> this command <span>to</span> <span>work</span> properly, your symbol path   <span>***</span>
<span>***</span>    must point <span>to</span> .pdb files that have <span>full</span> type information.      <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Certain .pdb files (such <span>as</span> the <span>public</span> OS symbols) do <span>not</span>      <span>***</span>
<span>***</span>    contain the required information.  Contact the <span>group</span> that      <span>***</span>
<span>***</span>    provided you <span>with</span> these symbols <span>if</span> you need this command <span>to</span>    <span>***</span>
<span>***</span>    <span>work</span>.                                                          <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Type referenced: ntdll!_PEB                                    <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>*************************************************************************</span>
<span>*************************************************************************</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Your debugger <span>is</span> <span>not</span> using the correct symbols                 <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    <span>In</span> <span>order</span> <span>for</span> this command <span>to</span> <span>work</span> properly, your symbol path   <span>***</span>
<span>***</span>    must point <span>to</span> .pdb files that have <span>full</span> type information.      <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Certain .pdb files (such <span>as</span> the <span>public</span> OS symbols) do <span>not</span>      <span>***</span>
<span>***</span>    contain the required information.  Contact the <span>group</span> that      <span>***</span>
<span>***</span>    provided you <span>with</span> these symbols <span>if</span> you need this command <span>to</span>    <span>***</span>
<span>***</span>    <span>work</span>.                                                          <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>***</span>    Type referenced: nt!IMAGE_NT_HEADERS32                         <span>***</span>
<span>***</span>                                                                   <span>***</span>
<span>*************************************************************************</span>
<span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\SYSTEM32\sechost.dll <span>-</span> 
<span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\system32\ole32.dll <span>-</span> 
<span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Windows\system32\RPCRT4.dll <span>-</span> 
<span>***</span> ERROR: Module <span>load</span> completed but symbols could <span>not</span> be loaded <span>for</span> C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn\Resources\<span>1033</span><span>\sqlevn70.rll
</span><span>***</span> ERROR: Symbol <span>file</span> could <span>not</span> be found.  Defaulted <span>to</span> export symbols <span>for</span> C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn\xpstar.dll <span>-</span><span> 
GetPageUrlData failed, server returned HTTP status </span><span>404</span><span>
URL requested: http:</span><span>//</span>watson.microsoft.com<span>/</span>StageOne<span>/</span>sqlservr_exe<span>/</span>2009_100_4319_<span>0</span><span>/</span>53a133d9<span>/</span>ntdll_dll<span>/</span>6_1_7601_<span>18247</span><span>/</span>521eaf24<span>/</span><span>80000003</span><span>/</span><span>00050590</span>.htm?Retriage<span>=</span><span>1</span><span>

FAULTING_IP: 
ntdll!DbgBreakPoint</span><span>+</span><span>0</span>
<span>00000000</span>`<span>77440590</span> cc              <span>int</span>     <span>3</span><span>

EXCEPTION_RECORD:  ffffffffffffffff </span><span>--</span><span> (.exr 0xffffffffffffffff)</span>
ExceptionAddress: <span>0000000077440590</span><span> (ntdll!DbgBreakPoint)
   ExceptionCode: </span><span>80000003</span> (<span>Break</span><span> instruction exception)
  ExceptionFlags: </span><span>00000000</span><span>
NumberParameters: </span><span>1</span><span>
   Parameter</span><span>[</span><span>0</span><span>]</span>: <span>0000000000000000</span><span>

FAULTING_THREAD:  </span><span>0000000000000444</span><span>

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

PROCESS_NAME:  sqlservr.exe

ADDITIONAL_DEBUG_TEXT:  
</span><span>Use</span> <span>'</span><span>!findthebuild</span><span>'</span> command <span>to</span> search <span>for</span><span> the target build information.
</span><span>If</span> the build information <span>is</span> available, run <span>'</span><span>!findthebuild -s ; .reload</span><span>'</span> <span>to</span> <span>set</span> symbol path <span>and</span> <span>load</span><span> symbols.

MODULE_NAME: ntdll

FAULTING_MODULE: 00000000773f0000 ntdll

DEBUG_FLR_IMAGE_TIMESTAMP:  521eaf24

ERROR_CODE: (NTSTATUS) </span><span>0x80000003</span> <span>-</span><span> {

EXCEPTION_CODE: (NTSTATUS) </span><span>0x80000003</span> (<span>2147483651</span>) <span>-</span><span> {

EXCEPTION_PARAMETER1:  </span><span>0000000000000000</span><span>

MOD_LIST: </span><span><</span>ANALYSIS<span>/></span><span>

PRIMARY_PROBLEM_CLASS:  WRONG_SYMBOLS

BUGCHECK_STR:  APPLICATION_FAULT_WRONG_SYMBOLS

LAST_CONTROL_TRANSFER:  </span><span>from</span> 00000000774e7f48 <span>to</span> <span>0000000077440590</span><span>

STACK_TEXT:  
</span><span>00000000</span>`0e7ff838 <span>00000000</span>`774e7f48 : <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span><span> : ntdll!DbgBreakPoint
</span><span>00000000</span>`0e7ff840 <span>00000000</span>`771e59ed : <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> : ntdll!DbgUiRemoteBreakin<span>+</span><span>0x38</span>
<span>00000000</span>`0e7ff870 <span>00000000</span>`7741c541 : <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> : kernel32!BaseThreadInitThunk<span>+</span><span>0xd</span>
<span>00000000</span>`0e7ff8a0 <span>00000000</span>`<span>00000000</span> : <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> <span>00000000</span>`<span>00000000</span> : ntdll!RtlUserThreadStart<span>+</span><span>0x21</span><span>


FOLLOWUP_IP: 
ntdll!DbgBreakPoint</span><span>+</span><span>0</span>
<span>00000000</span>`<span>77440590</span> cc              <span>int</span>     <span>3</span><span>

SYMBOL_STACK_INDEX:  </span><span>0</span><span>

SYMBOL_NAME:  ntdll!DbgBreakPoint</span><span>+</span><span>0</span><span>

FOLLOWUP_NAME:  MachineOwner

IMAGE_NAME:  ntdll.dll

STACK_COMMAND:  </span><span>~</span><span>41s ; kb

BUCKET_ID:  WRONG_SYMBOLS

FAILURE_BUCKET_ID:  WRONG_SYMBOLS_80000003_ntdll.dll!DbgBreakPoint

WATSON_STAGEONE_URL:  http:</span><span>//</span>watson.microsoft.com<span>/</span>StageOne<span>/</span>sqlservr_exe<span>/</span>2009_100_4319_<span>0</span><span>/</span>53a133d9<span>/</span>ntdll_dll<span>/</span>6_1_7601_<span>18247</span><span>/</span>521eaf24<span>/</span><span>80000003</span><span>/</span><span>00050590</span>.htm?Retriage<span>=</span><span>1</span><span>

Followup: MachineOwner
</span><span>--</span><span>-------</span>
View Code

 

 

符号搜索

命令“x”被用来进行符号的全局搜索,你可以把它直接就理解为search

如果什么参数都没有的话,它将列出当前调试环境下的所有局部变量,前提是要在有局部变量存在的情况下

x  <span>[</span><span>参数</span><span>]</span>  <span>[</span><span>模块!符号</span><span>]</span>

<span>0</span>:<span>010</span><span>></span> x sqlservr!SOS_Scheduler::Run<span>*</span> 
<span>00000000</span>`00290f10 sqlservr!SOS_Scheduler::RunTask <span>=</span> <span><</span>no type information<span>></span>

在SQL Server module (sqlservr)模块里面搜索所有符号里面包含SOS Scheduler (一个类)的符号

 

r命令

查看寄存器信息

r  //当前线程寄存器信息

~* r // 所有线程寄存器信息

<span>0</span>:<span>010</span><span>></span><span> r
rax</span><span>=</span>0000000002e520d8 rbx<span>=</span><span>0000000000000000</span> rcx<span>=</span><span>0000000003f0dac8
rdx</span><span>=</span>00000000000001e0 rsi<span>=</span>0000000000000fa0 rdi<span>=</span><span>000000000000041c
rip</span><span>=</span>00000000774412fa rsp<span>=</span>00000000079deb98 rbp<span>=</span><span>00000000804aa1a0
 r8</span><span>=</span>00000000000001e0  r9<span>=</span><span>0000000000000000</span> r10<span>=</span><span>0000000000000064</span><span>
r11</span><span>=</span>00000000079df190 r12<span>=</span>00000000079debc8 r13<span>=</span><span>0000000000000000</span><span>
r14</span><span>=</span><span>0000000000000000</span> r15<span>=</span><span>0000000008d808f8
iopl</span><span>=</span><span>0</span><span>         nv up ei ng nz na po cy
cs</span><span>=</span><span>0033</span>  ss<span>=</span>002b  ds<span>=</span>002b  es<span>=</span>002b  fs<span>=</span><span>0053</span>  gs<span>=</span>002b             efl<span>=</span><span>00000285</span><span>
ntdll!NtWaitForSingleObject</span><span>+</span><span>0xa</span><span>:
</span><span>00000000</span>`774412fa c3              ret

CPU上会有一些寄存器,它们是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果的

看一下上面的rax寄存器是一个多用途寄存器一般用来保存返回的值和操作的结果。

“rax”是64位寄存器,而对应32位平台,他的名字叫 “eax”。另外由于是64位CPU所以寄存器的大小也是64位

每一个数字代表4位或 半个字节,因此在寄存器里面存储的数值两个数字代表一个字节,下面rax寄存器里面存储的数就是代表一个64位数( 16 x 4 = 64 bits)

rax=0000000002e520d8

 

还有一些特别的寄存器,例如rip 和rsp 寄存器

rip寄存器保存了当前的指令指针,他指向下一个要执行的指令

rip寄存器包含一个指向当前栈位置的指针,我们可以使用中括号([])获取寄存器的实际地址并且里面用汇编代码显示出来

<span>0</span>:<span>010</span><span>></span> u <span>[</span><span>rip</span><span>]</span><span>
ntdll!NtWaitForSingleObject</span><span>+</span><span>0xa</span><span>:
</span><span>00000000</span><span>`774412fa c3              ret
</span><span>00000000</span>`774412fb 0f1f440000      nop     dword ptr <span>[</span><span>rax+rax</span><span>]</span><span>
ntdll!NtCallbackReturn:
</span><span>00000000</span>`<span>77441300</span><span> 4c8bd1          mov     r10,rcx
</span><span>00000000</span>`<span>77441303</span> b802000000      mov     eax,<span>2</span>
<span>00000000</span>`<span>77441308</span><span> 0f05            syscall
</span><span>00000000</span><span>`7744130a c3              ret
</span><span>00000000</span>`7744130b 0f1f440000      nop     dword ptr <span>[</span><span>rax+rax</span><span>]</span><span>
ntdll!NtReadFile:
</span><span>00000000</span>`<span>77441310</span> 4c8bd1          mov     r10,rcx

我们看到rip里面指向ntdll!NtWaitForSingleObject,这个函数位于在文章前面线程10的stack trace 的最顶层

u 命令

显示指定的内存中的程序代码的反汇编,如果要反汇编某一个地址,直接用u 命令加地址

如果存在符号文件,也可以这样直接加函数名:

 u user32!SendMessagew

 

 

当你进行live debug的时候,你可能想在sqlserver运行的时候下断点,你可以使用符号名或函数起初地址初设置断点

然后你可以使用条件断点当某个条件成立的时候触发中断

例子

<span>0</span>:<span>010</span><span>></span> bp sqlservr<span>!<</span><span>function</span> <span>or</span> method call<span>></span>

bp命令

<span>bp:

命令bp是BreakPoint的缩写。其指令格式如下:

bp</span><span>[</span><span>ID</span><span>]</span> <span>[</span><span>Options</span><span>]</span> <span>[</span><span>Address [Passes</span><span>]</span>] <span>[</span><span>"CommandString"</span><span>]</span><span>


参数Address表示需设置断点的地址,缺省情况下使用当前指令指针(EIP)的地址。ID是断点号,一般不手动设置,由调试器内部编号。Passes是一个整数值,即第几次经过断点所在代码时,调试器才需要中断执行,默认为1,即每次都中断。CommandString用来设置一组命令,当断点发生的时候,就执行这一组命令,比如可以把它设置为“k”,这样断点处就会输出当前的调用栈。</span>

断点相关命令

<span>bl:列出所有断点
bd:禁止断点,d代表Disable。如bd </span><span>1</span><span>,禁止断点1。断点被禁止后将不起作用,但亦未删除。
be:恢复断点,e代表Enable。恢复被禁止的断点。如be 1恢复1号断点。
bc:清除断点,如:bc </span><span>1</span>,清除断点1;bc <span>*</span><span>,清除全部断点。
br:序号管理,r代表ReNumber,即重新排序。如:br </span><span>2</span> <span>0</span>,将2号断点重设为0号断点。

 

比如,我想在sqlservr!SOS_Scheduler::RunTask 这个符号上下断点

首先用x命令列出跟sqlservr!SOS_Scheduler::R*相关的符号名,以保证名字没有错误

<span>0</span>:<span>010</span><span>></span> x sqlservr!SOS_Scheduler::R<span>*</span>
<span>00000000</span>`0179c6b0 sqlservr!SOS_Scheduler::RemoveFromCompletedTasks <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`0329e200 sqlservr!SOS_Scheduler::RemoveFromPendingQueue <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`013458c4 sqlservr!SOS_Scheduler::ResumeBulkInternal <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`00d8f0cc sqlservr!SOS_Scheduler::RunTask <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`032a4a68 sqlservr!SOS_Scheduler::RetrieveTask <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`00d85448 sqlservr!SOS_Scheduler::ResumeBulk <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`01345a90 sqlservr!SOS_Scheduler::RunnableQueueInsertBulk <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`01344c90 sqlservr!SOS_Scheduler::RemoveFromAbortedQueue <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`00d834f8 sqlservr!SOS_Scheduler::Resume <span>=</span> <span><</span>no type information<span>></span>
<span>00000000</span>`00d835c4 sqlservr!SOS_Scheduler::RunnableQueueInsert <span>=</span> <span><</span>no type information<span>></span>

下断点

<span>0</span>:<span>010</span><span>></span> bp sqlservr!SOS_Scheduler::RunTask 

列出所有断点

<span>0</span>:<span>010</span><span>></span><span> bl
 </span><span>0</span> e <span>00000000</span>`00d8f0cc     <span>0001</span> (<span>0001</span>)  <span>0</span>:<span>****</span> sqlservr!SOS_Scheduler::RunTask

 

清除第一个断点

<span>0</span>:<span>010</span><span>></span> bc <span>1</span>

检查断点是否清除了

<span>0</span>:<span>010</span><span>></span> bl

 

 

最后说一下获取帮助的命令

? // 打印出所有标准命令

<span>0</span>:<span>010</span><span>></span><span> ?

</span><span>Open</span> debugger.chm <span>for</span><span> complete debugger documentation

B</span><span>[</span><span>C|D|E</span><span>][</span><span><bps></span><span>]</span> <span>-</span> clear<span>/</span>disable<span>/</span><span>enable breakpoint(s)
BL </span><span>-</span><span> list breakpoints
BA </span><span><</span>access<span>></span> <span><</span>size<span>></span> <span><</span>addr<span>></span> <span>-</span> <span>set</span><span> processor breakpoint
BP </span><span><</span>address<span>></span> <span>-</span> <span>set</span><span> soft breakpoint
D</span><span>[</span><span>type</span><span>][</span><span><range></span><span>]</span> <span>-</span> <span>dump</span><span> memory
DT </span><span>[</span><span>-n|y</span><span>]</span> <span>[</span><span>[mod!</span><span>]</span>name] <span>[</span><span>[-n|y</span><span>]</span><span>fields]
   </span><span>[</span><span>address</span><span>]</span> <span>[</span><span>-l list</span><span>]</span> <span>[</span><span>-a[</span><span>]</span><span>|</span>c<span>|</span>i<span>|</span>o<span>|</span>r<span>[</span><span>#</span><span>]</span><span>|</span>v] <span>-</span> <span>dump</span><span> using type information
DV </span><span>[</span><span><name></span><span>]</span> <span>-</span> <span>dump</span><span> local variables
E</span><span>[</span><span>type</span><span>]</span> <span><</span>address<span>></span> <span>[</span><span><values></span><span>]</span> <span>-</span> enter memory <span>values</span><span>
G</span><span>[</span><span>H|N</span><span>]</span> <span>[</span><span>=<address> [<address>...</span><span>]</span>] <span>-</span> <span>go</span><span>
K </span><span><</span><span>count</span><span>></span> <span>-</span><span> stacktrace
KP </span><span><</span><span>count</span><span>></span> <span>-</span> stacktrace <span>with</span><span> source arguments
LM</span><span>[</span><span>k|l|u|v</span><span>]</span> <span>-</span><span> list modules
LN </span><span><</span>expr<span>></span> <span>-</span><span> list nearest symbols
P </span><span>[</span><span>=<addr></span><span>]</span> <span>[</span><span><value></span><span>]</span> <span>-</span> step <span>over</span><span>
Q </span><span>-</span><span> quit
R </span><span>[</span><span>[<reg> [= <expr></span><span>]</span>]] <span>-</span> <span>view</span> <span>or</span> <span>set</span><span> registers
S</span><span>[</span><span><opts></span><span>]</span> <span><</span>range<span>></span> <span><</span><span>values</span><span>></span> <span>-</span><span> search memory
SX </span><span>[</span><span>{e|d|i|n} [-c "Cmd1"</span><span>]</span> <span>[</span><span>-c2 "Cmd2"</span><span>]</span> <span>[</span><span>-h</span><span>]</span> {Exception<span>|</span>Event<span>|*</span>}] <span>-</span><span> event filter
T </span><span>[</span><span>=<address></span><span>]</span> <span>[</span><span><expr></span><span>]</span> <span>-</span> trace <span>into</span><span>
U </span><span>[</span><span><range></span><span>]</span> <span>-</span><span> unassemble
version </span><span>-</span> show debuggee <span>and</span><span> debugger version
X </span><span>[</span><span><*|module>!</span><span>]</span><span><*|</span>symbol<span>></span> <span>-</span> <span>view</span><span> symbols
? </span><span><</span>expr<span>></span> <span>-</span><span> display expression
?? </span><span><</span>expr<span>></span> <span>-</span> display C<span>++</span><span> expression
$</span><span><</span> <span><</span>filename<span>></span> <span>-</span> take input <span>from</span> a command <span>file</span>

 

.help // 打印出所有元命令

.hh // 打开windbg的chm帮助文件 弹出帮助文件

windbg<span>></span> .hh 

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

command /? // 打印命令command具体参数用法

 

 

当然Windbg还有非常复杂的玩法,调试SQLSERVER也是很复杂,不是一般初学者可以驾驭

 

参考文章:

windbg调试命令

Windbg调试命令详解

windbg调试命令1(k、u、x)

 

 

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

PHP教程
1535
276
如何使用LeakSanitizer调试C++内存泄漏? 如何使用LeakSanitizer调试C++内存泄漏? Jun 02, 2024 pm 09:46 PM

如何使用LeakSanitizer调试C++内存泄漏?安装LeakSanitizer。通过编译标志启用LeakSanitizer。运行应用程序并分析LeakSanitizer报告。识别内存分配类型和分配位置。修复内存泄漏,确保释放所有动态分配的内存。

Java 并发编程中如何进行并发测试和调试? Java 并发编程中如何进行并发测试和调试? May 09, 2024 am 09:33 AM

并发测试和调试Java并发编程中的并发测试和调试至关重要,以下技术可供使用:并发测试:单元测试:隔离并测试单个并发任务。集成测试:测试多个并发任务之间的交互。负载测试:评估应用程序在高负载下的性能和可扩展性。并发调试:断点:暂停线程执行并检查变量或执行代码。日志记录:记录线程事件和状态。堆栈跟踪:识别异常源头。可视化工具:监视线程活动和资源使用情况。

如何调试 PHP 异步代码 如何调试 PHP 异步代码 May 31, 2024 am 09:08 AM

调试PHP异步代码的工具包括:Psalm:静态分析工具,可发现潜在错误。ParallelLint:检查异步代码并提供建议的工具。Xdebug:用于调试PHP应用程序的扩展,可通过启用会话并逐步执行代码来调试。其他技巧还包括使用日志记录、断言、局部运行代码和编写单元测试。

PHP 调试错误:常见错误的指南 PHP 调试错误:常见错误的指南 Jun 05, 2024 pm 03:18 PM

常见的PHP调试错误包括:语法错误:检查代码语法,确保没有错误。未定义变量:在使用变量之前,确保已将其初始化并赋值。缺失分号:为所有代码块添加分号。函数未定义:检查函数名拼写是否正确,并确保已加载正确的文件或PHP扩展。

什么是Bitget Launchpool?如何使用Bitget Launchpool? 什么是Bitget Launchpool?如何使用Bitget Launchpool? Jun 07, 2024 pm 12:06 PM

BitgetLaunchpool是一个为所有加密货币爱好者而设计的动态平台。BitgetLaunchpool以其独特的产品脱颖而出。在这里,您可以质押您的代币来解锁更多奖励,包括空投、高额回报,以及专属早期参与者的丰厚奖池。什么是BitgetLaunchpool?BitgetLaunchpool是一个加密货币平台,可以透过用户友善的条款和条件来质押和赚取代币。透过在Launchpool中投入BGB或其他代币,用户有机会获得免费空投、收益和参与丰厚的奖金池。质押资产的收益在T+1小时内计算,奖励按

如何调试 C++ 程序中的死锁? 如何调试 C++ 程序中的死锁? Jun 03, 2024 pm 05:24 PM

死锁是一种并发编程中的常见错误,发生在多个线程等待彼此持有的锁时。可以通过使用调试器检测死锁,分析线程活动并识别涉及的线程和锁,从而解决死锁。解决死锁的方法包括避免循环依赖、使用死锁检测器和使用超时。在实践中,通过确保线程按相同的顺序获取锁或使用递归锁或条件变量可以避免死锁。

Navicat导入数据库备份文件(如.bak)的恢复方法 Navicat导入数据库备份文件(如.bak)的恢复方法 Jun 04, 2025 pm 06:51 PM

使用Navicat恢复.bak文件的方法如下:1.打开Navicat,连接到SQLServer实例。2.创建新数据库或选择现有数据库。3.在查询编辑器中输入并执行RESTOREDATABASESQL语句,确保路径和名称正确。4.注意数据库名称、文件路径、WITHREPLACE和MOVE选项的使用,以确保恢复成功。

如何调试 C++ 程序中的输入/输出错误? 如何调试 C++ 程序中的输入/输出错误? May 31, 2024 pm 06:11 PM

调试C++输入/输出错误的方法包括:检查变量值、使用异常处理和检查流状态。这些技术可帮助您快速准确地找出和解决I/O错误,确保您的程序正确处理输入和输出。

See all articles