調試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的運行,不要在生產環境上亂試?。?/strong>
在調試的時候你可以在命令框里輸入一些命令
首先,一個stack trace很明顯是對應一個線程的,SQLSERVER是一個多線程應用程序,要獲得sqlserver的線程列表,使用命令:~
使用Windbg版本:6.12.0002.633 AMD64
SQL版本:SQL2008R2
操作系統:WIN2008R2
我們附加SQL進程
SQL進程ID是6192
如果要退出,記得輸入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的運行,不要在生產環境上亂試?。?/strong>
從上圖中可以看到我們有47個線程 ,線程從0開始計數。
在左邊邊緣的句點指明當前正在上下文中(in context)運行的線程,在提示框中(0:046>)也指明了當前上下文的線程的序數是46
第一列的數字只是給調試器使用的數字序數列
接下來那一列才是進程:線程列,調試器以hex的形式來顯示(pid.tid),比如上面的46 Id: 1830.18a8 Suspend:1
1830的十進制是6192,18a8的十進制是6312
那么 Id: 1830.18a8就表示進程id是6192:線程id是6312
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版本
SQLSERVER是32位還是64位,是SQL2008還是SQL2008R2
如果輸入 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 ret0:010> kChild-SP RetAddr Call Site00000000`079deb98 000007fe`fd2110dc ntdll!NtWaitForSingleObject+0xa00000000`079deba0 00000000`00d83b55 KERNELBASE!WaitForSingleObjectEx+0x9c00000000`079dec40 00000000`00d834ca sqlservr!SOS_Scheduler::SwitchContext+0x26d00000000`079df0d0 00000000`00d82710 sqlservr!SOS_Scheduler::SuspendNonPreemptive+0xca00000000`079df110 00000000`00d829bc sqlservr!SOS_Scheduler::Suspend+0x2d00000000`079df140 00000000`00da2eab sqlservr!EventInternal<Spinlock<154,1,0> >::Wait+0x1a800000000`079df190 00000000`01949951 sqlservr!CTraceManagementTask::Invoke+0xbe00000000`079df1f0 00000000`00d8eb40 sqlservr!CTraceBatchTask::Task+0x1ad00000000`079df2d0 00000000`00d8f15a sqlservr!SOS_Task::Param::Execute+0x12a00000000`079df3e0 00000000`00d8ef9f sqlservr!SOS_Scheduler::RunTask+0x9600000000`079df440 00000000`0135e8ee sqlservr!SOS_Scheduler::ProcessTasks+0x12800000000`079df4b0 00000000`0135eb25 sqlservr!SchedulerManager::WorkerEntryPoint+0x2d200000000`079df590 00000000`00ea7631 sqlservr!SystemThread::RunWorker+0xcc00000000`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+0x17300000000`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+0x10400000000`079df780 00000000`7741c541 kernel32!BaseThreadInitThunk+0xd00000000`079df7b0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:010> dc 00000000`079df4b000000000`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> dc00000000`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....-
新聞熱點
疑難解答