调试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 // 分离调试

.restart // 重启并调试

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

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

 

 

附加成功了,我们看到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命令,我们可以对这个线程设置上下文或查看

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

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

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

使用命令:

~36s

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

然后输入命令 : k  

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

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

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

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

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

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

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

 

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

先用 ~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号线程的栈情况

** 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 00002dec 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 Toolkit\
Extension 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

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-07-01
  • 2021-11-04
  • 2022-01-10
  • 2022-01-20
猜你喜欢
  • 2021-09-01
  • 2021-11-12
  • 2021-06-27
  • 2021-08-10
  • 2021-05-25
相关资源
相似解决方案