SQL Server 转储 II

四、使用windbg

在了解上述知识后,就可以使用windbg来进行分析了。

1,windbg环境的配置

到微软的网站下载windbg后直接安装,安装完成后,需要配置symbols的path,打开windbg,File --> Symbols File Path 在弹出的对话框输入

srv*c:/symbols*http://msdl.microsoft.com/download/symbols

其中c:/symbols是本地硬盘的文件夹,在使用时,windbg会到http://msdl.microsoft.com/download/symbols下载相关的symbols,也可以自己手工下载相关操作系统的symbols。

配置好,可以使用.reload命令来强制下载某个symbols,如:

.reload /f sqlservr.exe

具体的命令可以参考windbg的帮助文档。

2,打开mdmp文件

打开windbg,File --> Open Crash Dump,选择mdump文件,在弹出的对话框里点击yes

3,分析mdmp

在下面的对话框输入 ~ 会出现线程的信息

0:000> ~
. 0 Id: 384.608 Suspend: 1 Teb: 7ffdd000 Unfrozen
  1 Id: 384.698 Suspend: 1 Teb: 7ffda000 Unfrozen
  2 Id: 384.6a8 Suspend: 1 Teb: 7ffd9000 Unfrozen
  3 Id: 384.6a4 Suspend: 1 Teb: 7ffd8000 Unfrozen
  4 Id: 384.6b0 Suspend: 1 Teb: 7ffd7000 Unfrozen
  5 Id: 384.6ac Suspend: 1 Teb: 7ffd6000 Unfrozen
  6 Id: 384.6c8 Suspend: 1 Teb: 7ffd5000 Unfrozen
  7 Id: 384.6dc Suspend: 1 Teb: 7ffd4000 Unfrozen
  8 Id: 384.6e0 Suspend: 1 Teb: 7ffd3000 Unfrozen
  9 Id: 384.108 Suspend: 1 Teb: 7ff9f000 Unfrozen
  10 Id: 384.6e8 Suspend: 1 Teb: 7ff9e000 Unfrozen
  11 Id: 384.6e4 Suspend: 1 Teb: 7ff9d000 Unfrozen
  12 Id: 384.604 Suspend: 1 Teb: 7ff9c000 Unfrozen
  13 Id: 384.714 Suspend: 1 Teb: 7ff9b000 Unfrozen
  14 Id: 384.718 Suspend: 1 Teb: 7ff9a000 Unfrozen
  15 Id: 384.71c Suspend: 1 Teb: 7ff99000 Unfrozen
  16 Id: 384.720 Suspend: 1 Teb: 7ff98000 Unfrozen
  17 Id: 384.728 Suspend: 1 Teb: 7ffdc000 Unfrozen
  18 Id: 384.730 Suspend: 1 Teb: 7ff97000 Unfrozen
  19 Id: 384.74c Suspend: 1 Teb: 7ff96000 Unfrozen
  20 Id: 384.784 Suspend: 1 Teb: 7ff95000 Unfrozen
  21 Id: 384.788 Suspend: 1 Teb: 7ff94000 Unfrozen
  22 Id: 384.1e0 Suspend: 1 Teb: 7ff93000 Unfrozen
  23 Id: 384.284 Suspend: 1 Teb: 7ff92000 Unfrozen
  24 Id: 384.280 Suspend: 1 Teb: 7ff91000 Unfrozen
  25 Id: 384.23c Suspend: 1 Teb: 7ff8f000 Unfrozen
  26 Id: 384.3d0 Suspend: 1 Teb: 7ff8e000 Unfrozen
  27 Id: 384.3d4 Suspend: 1 Teb: 7ff8d000 Unfrozen
  28 Id: 384.3d8 Suspend: 1 Teb: 7ff8c000 Unfrozen
  29 Id: 384.204 Suspend: 1 Teb: 7ff8b000 Unfrozen
  30 Id: 384.43c Suspend: 1 Teb: 7ff8a000 Unfrozen
  31 Id: 384.450 Suspend: 1 Teb: 7ff89000 Unfrozen
  32 Id: 384.454 Suspend: 1 Teb: 7ff88000 Unfrozen
  33 Id: 384.458 Suspend: 1 Teb: 7ff87000 Unfrozen
  34 Id: 384.45c Suspend: 1 Teb: 7ff86000 Unfrozen
  35 Id: 384.464 Suspend: 1 Teb: 7ff84000 Unfrozen
  36 Id: 384.44c Suspend: 1 Teb: 7ff83000 Unfrozen
  37 Id: 384.1e8 Suspend: 1 Teb: 7ffdb000 Unfrozen
  38 Id: 384.1cc Suspend: 1 Teb: 7ff82000 Unfrozen
  39 Id: 384.1684 Suspend: 1 Teb: 7ff80000 Unfrozen
  40 Id: 384.c38 Suspend: 1 Teb: 7ff90000 Unfrozen
  41 Id: 384.1048 Suspend: 1 Teb: 7ff85000 Unfrozen
  42 Id: 384.140c Suspend: 1 Teb: 7ff7f000 Unfrozen
  43 Id: 384.a18 Suspend: 1 Teb: 7ff81000 Unfrozen

在我的这个例子中,我的spid在循环运行一个select命令,从sysprocesses中,可以看到spid对应的kpid是488

spid kpid
51 0
52 488

488转化为16进制刚好为1e8 ,对应的序号是37。

那我们如果想看线程37的内容,可以先使用 ~37s命令切换到线程37的上下文中

0:000> ~37s
eax=00000000 ebx=3f20f344 ecx=1f8dcf08 edx=00000001 esi=000009b5 edi=00000000
eip=7c92e514 esp=3f20f238 ebp=3f20f29c iopl=0 nv up ei ng nz ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297
ntdll!KiFastSystemCallRet:
7c92e514 c3 ret

看起来是CPU的寄存器信息,可惜这些还看不太懂,不然可以更深入了。

接着用k命令,查看具体的函数调用信息

0:037> k
ChildEBP RetAddr   
3f20f234 7c92df5a ntdll!KiFastSystemCallRet
3f20f238 7c8025db ntdll!ZwWaitForSingleObject+0xc
3f20f29c 7c802542 kernel32!WaitForSingleObjectEx+0xa8
3f20f2b0 011e7ced kernel32!WaitForSingleObject+0x12
3f20f324 011e7ddb sqlservr!Np::StatusWriteNoComplPort+0x9f
3f20f354 011e7ea2 sqlservr!SNIStatusWriteNoComplPort+0x82
3f20f374 012a8ae0 sqlservr!TDSSNIClient::WriteStatus+0x6a
3f20f4a0 0153d30c sqlservr!write_data+0x1a6
3f20f4d0 0117492e sqlservr!flush_buffer+0xdf
3f20f6a0 015490b6 sqlservr!CKatmaiTds::SendRowImpl+0x2faf
3f20f6ac 01532f0d sqlservr!CValOdsRow::SetDataX+0x29
3f20f6bc 01532d8b sqlservr!SetMultData+0x1e
3f20f734 0154962f sqlservr!CEs::GeneralEval4+0xd0
3f20f740 01547825 sqlservr!CEs::Eval+0x13
3f20f7f8 015499af sqlservr!CXStmtQuery::ErsqExecuteQuery+0x409
3f20f85c 015401c3 sqlservr!CXStmtSelect::XretExecute+0x268
3f20f8f8 01540cc0 sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0x28d
3f20f9e0 01540686 sqlservr!CMsqlExecContext::FExecute+0x70e
3f20fa84 0153cf8c sqlservr!CSQLSource::Execute+0x598
3f20fc08 01539f79 sqlservr!process_request+0x2f0

从下面的内容,可以看出几点(个人观点:) )

3f20f354 011e7ea2 sqlservr!SNIStatusWriteNoComplPort+0x82
3f20f374 012a8ae0 sqlservr!TDSSNIClient::WriteStatus+0x6a
3f20f4a0 0153d30c sqlservr!write_data+0x1a6
3f20f4d0 0117492e sqlservr!flush_buffer+0xdf

3f20f7f8 015499af sqlservr!CXStmtQuery::ErsqExecuteQuery+0x409
3f20f85c 015401c3 sqlservr!CXStmtSelect::XretExecute+0x268
3f20f8f8 01540cc0 sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0x28d
3f20f9e0 01540686 sqlservr!CMsqlExecContext::FExecute+0x70e

从底往上看,可以看到这是一个select动作,进行select时,先对内存的一些缓存进行清除(flush_buffer),接着便是写入数据(write_data),然后再发送写状态(TDSSNIClient::WriteStatus),由于一直循环所以会有写未完成的提示(SNIStatusWriteNoComplPort)。这也基本符合一个select的动作。

如果遇到错误时,在函数调用中一般会抛出raiseerror等内容,类似如下:

00000000`220ce2d0 00000000`013a3d41 sqlservr!ex_raise2+0xcdd8bf

00000000`220ce630 00000000`02deb8ce sqlservr!ex_raise+0x51  

这时,基本可以判断出现问题的原因了。

3,其他

windbg的功能是很强大的,是通往sql server内部一个强大工具。要想了解的话,估计得好好研究下<windows internal>,有兴趣的可以自行深入。

五、小结

只是抛砖引玉,并且还处于入门级,希望有这方面兴趣的朋友也能多多分享!

 

本文来自CSDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值