好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

调试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进程

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

.detach  //   分离调试

.restart   //   重启并调试

.  kill   //   强制结束当前调试

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

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

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

进程环境块(Process Enviroment Block)Peb

线程环境块(Thread Enviroment Block)Teb

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

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

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

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

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

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

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

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

tid:thread id

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

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

例如:

提供函数参数 输入 kv

提供frame 号码 输入 kn

提供内存使用 输入 kf

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

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

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

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

使用命令:

 ~ 36s 

然后输入命令 : k

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

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

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

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

大家可以对比一下 ~ 36s 命令和 k 命令

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

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

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

输入 kn 加上frame号码

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

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

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

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

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

lmvm sqlservr 

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

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

deferred:表示延迟加载

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

内存命令

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

例如

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

dd:只显示 4字节DWORD格式

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

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

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

 0 : 010  >  dc  00000000  `079df4b0
  00000000 `079df4b0   00000000   00000000  804aa1a0  00000000    ..........J.....
  00000000 `079df4c0  fff914a8 000007ff  00000000   00000000    ................
  00000000 `079df4d0  8fe8cfb8 00002 dec   00000000   00000000   ..... -  ..........
  00000000 `079df4e0  032af070  00000000   00000000   00000000   p. *  .............
  00000000 `079df4f0  08d80080  00000000   00000000   00000000    ................
  00000000 `079df500   00000001   00000000   fff914a8 000007ff  ................
  00000000 `079df510   00000006   00000000   fffffffe ffffffff  ................
  00000000  `079df520  fff914a8 000007ff fff9155c 000007ff  ........\.......
  0 : 010  >   dc
  00000000 `079df530  804aa1a0  00000000   fff90000 000007ff  ..J.............
  00000000 `079df540  271516fd  00000000  fffffffe ffffffff  ... '  ............
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.._...  

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

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

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

我们会接着介绍下面命令

 vertarget
.chain
!analyze
x
r
u
bp, bl, bc  

vertarget命令

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

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

.chain命令

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

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

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

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

!analyze -v

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

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

参数

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

 0 : 010  >  !analyze  -  v
  ******************************************************************************* 
 *                                                                               * 
 *                         Exception Analysis                                    * 
 *                                                                               * 
 ******************************************************************************* 

 *****  OS symbols are WRONG. Please fix symbols  to   do analysis.

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

FAULTING_IP: 
ntdll!DbgBreakPoint  +  0 
 00000000 ` 77440590  cc               int       3  

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

FAULTING_THREAD:    0000000000000444  

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

PROCESS_NAME:  sqlservr.exe

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

MODULE_NAME: ntdll

FAULTING_MODULE: 00000000773f0000 ntdll

DEBUG_FLR_IMAGE_TIMESTAMP:  521eaf24

ERROR_CODE: (NTSTATUS)   0x80000003   -   {

EXCEPTION_CODE: (NTSTATUS)   0x80000003  ( 2147483651 )  -   {

EXCEPTION_PARAMETER1:    0000000000000000  

MOD_LIST:    ANALYSIS />  

PRIMARY_PROBLEM_CLASS:  WRONG_SYMBOLS

BUGCHECK_STR:  APPLICATION_FAULT_WRONG_SYMBOLS

LAST_CONTROL_TRANSFER:    from  00000000774e7f48  to   0000000077440590  

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


FOLLOWUP_IP: 
ntdll!DbgBreakPoint  +  0 
 00000000 ` 77440590  cc               int       3  

SYMBOL_STACK_INDEX:    0  

SYMBOL_NAME:  ntdll!DbgBreakPoint  +  0  

FOLLOWUP_NAME:  MachineOwner

IMAGE_NAME:  ntdll.dll

STACK_COMMAND:    ~  41s ; kb

BUCKET_ID:  WRONG_SYMBOLS

FAILURE_BUCKET_ID:  WRONG_SYMBOLS_80000003_ntdll.dll!DbgBreakPoint

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

Followup: MachineOwner
  --  -------  

View Code

符号搜索

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

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

x   [  参数  ]    [  模块!符号  ]  

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

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

r命令

查看寄存器信息

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

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

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

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

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

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

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

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

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

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

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

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

u 命令

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

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

 u user32!SendMessagew 

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

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

例子

 0 : 010  >  bp sqlservr !  function   or  method call >  

bp命令

 bp:

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

bp  [  ID  ]   [  Options  ]   [  Address [Passes  ] ]  [  "CommandString"  ]  


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

断点相关命令

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

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

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

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

下断点

 0 : 010  >  bp sqlservr!SOS_Scheduler::RunTask  

列出所有断点

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

清除第一个断点

 0 : 010  >  bc  1  

检查断点是否清除了

 0 : 010  >  bl 

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

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

 0 : 010  >   ?

  Open  debugger.chm  for   complete debugger documentation

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

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

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

windbg >  .hh  

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

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

参考文章:

windbg调试命令

Windbg调试命令详解

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

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

查看更多关于调试SQLSERVER(三)使用Windbg调试SQLSERVER的一些命令的详细内容...

  阅读:49次