国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

調(diào)試SQLSERVER (二)使用Windbg調(diào)試SQLSERVER的環(huán)境設(shè)置

2024-07-21 02:48:11
字體:
供稿:網(wǎng)友
調(diào)試SQLSERVER (二)使用Windbg調(diào)試SQLSERVER的環(huán)境設(shè)置調(diào)試SQLSERVER (二)使用Windbg調(diào)試SQLSERVER的環(huán)境設(shè)置

調(diào)試SQLSERVER (一)生成dump文件的方法調(diào)試SQLSERVER (三)使用Windbg調(diào)試SQLSERVER的一些命令

大家知道在Windows里面,調(diào)試可以分為兩個(gè)領(lǐng)域:

1、內(nèi)核態(tài)調(diào)試

2、用戶態(tài)調(diào)試

一般的程序都是運(yùn)行在用戶態(tài),包括SQLSERVER,SQLServer 會(huì)依賴于操作系統(tǒng)的Win32/Win64 API去調(diào)用I/O或者其他他需要的服務(wù)

用戶態(tài)程序調(diào)試和內(nèi)核態(tài)程序調(diào)試是不太一樣的,即使有些命令是一樣的

還有另外一個(gè)要注意的是live debug和dump file

live debug:直接附加調(diào)試器到進(jìn)程--使進(jìn)程hang住,使被調(diào)試程序不能繼續(xù)執(zhí)行代碼

dump file :通常是一個(gè)dump文件,dump文件是進(jìn)程生成的當(dāng)時(shí)這個(gè)進(jìn)程的所有或部分內(nèi)存內(nèi)容,并且可以被調(diào)試器讀取

full dump文件 通常的擴(kuò)展名是.dmp ,文件里面一般不包含已經(jīng)paged out 的內(nèi)存內(nèi)容

mini dump文件 通常的擴(kuò)展名是.mdmp ,一般只包含線程棧和加載的模塊名

Windbg: 是一個(gè)GUI調(diào)試器工具并且可以調(diào)試內(nèi)核態(tài)和用戶態(tài)程序,除了Windbg調(diào)試器 當(dāng)然還有其他調(diào)試器 ,例如kd, cdb, ntsd


簡(jiǎn)單復(fù)習(xí)

應(yīng)用程序以進(jìn)程運(yùn)行,這里我們關(guān)注的進(jìn)程是sqlservr.exe ,在用戶態(tài)調(diào)試下,我們會(huì)調(diào)試一個(gè)單獨(dú)的進(jìn)程,無論是使用live debug(附加進(jìn)程方式)還是讀取一個(gè)dump文件

在調(diào)試的時(shí)候都能看到進(jìn)程的內(nèi)存空間。在內(nèi)核態(tài)調(diào)試?yán)铮覀兛梢钥吹剿羞M(jìn)程和他們的內(nèi)存空間(注意:在dump文件里面我們?cè)L問不到當(dāng)生成dump文件的時(shí)候

已經(jīng)被paged out 的那部分內(nèi)存地址)

stack trace:?jiǎn)蝹€(gè)線程里面執(zhí)行的代碼的棧,一個(gè)線程可以有用戶態(tài)棧內(nèi)核態(tài)棧,在用戶態(tài)調(diào)試?yán)锩妫覀冎荒芸吹矫總€(gè)線程的用戶態(tài)棧

一個(gè)stack trace是一個(gè)線程的一系列函數(shù)調(diào)用的list

stack是一個(gè)LIFO結(jié)構(gòu)(last in first out)意思是后進(jìn)先出,術(shù)語叫做push stack 和pop stack

棧的讀取是自底向上的,最上面的調(diào)用是當(dāng)前正在執(zhí)行的代碼

下面的例子

Child SP (Stack Pointer)

RetAddr (Return Address)

stack trace里面可以跟蹤系統(tǒng)的執(zhí)行順序和調(diào)用代碼的返回,調(diào)試器會(huì)構(gòu)造stack trace 給我們以便于更好的分析

Child-SP          RetAddr           Call Site 00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa 00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110 00000000`09cbeaa0 00000000`00bc4575 sqlservr+0x1c99e 00000000`09cbed40 00000000`00bc3ea8 sqlservr+0x4575 00000000`09cbed80 00000000`00bdcfad sqlservr+0x3ea8 00000000`09cbf370 00000000`01139d9c sqlservr+0x1cfad 00000000`09cbf430 00000000`032b34c7 sqlservr+0x579d9c 00000000`09cbf650 00000000`00bd2abb sqlservr!TlsGetValueForMsxmlSQL+0x4706d7 00000000`09cbf6c0 00000000`00bd0fda sqlservr+0x12abb 00000000`09cbf7e0 00000000`00bd2665 sqlservr+0x10fda 00000000`09cbf870 00000000`0117abb0 sqlservr+0x12665 00000000`09cbf8e0 00000000`0117c4b0 sqlservr+0x5babb0 00000000`09cbf9a0 00000000`0117a060 sqlservr+0x5bc4b0 00000000`09cbf9d0 00000000`0117a9ef sqlservr+0x5ba060 00000000`09cbfa60 00000000`734937d7 sqlservr+0x5ba9ef 00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47 00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104 00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd 00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21

在配置調(diào)試器的過程中,最后的步驟是匹配符號(hào),我們打開Windbg的時(shí)候我們必須設(shè)置我們的符號(hào)文件路徑

Symbolic Debugging Files(符號(hào)調(diào)試文件):幫助調(diào)試器把內(nèi)存里面的各自的函數(shù),類,變量名在內(nèi)存的位置 匹配到相應(yīng)的內(nèi)存地址和位移

如果沒有Symbolic Debugging Files,那么我們將會(huì)看到下面只有memory addresses 的stack trace

符號(hào)文件的擴(kuò)展名通常是pdb(如果大家寫C#代碼的時(shí)候肯定都會(huì)看到過在debug的時(shí)候看到bin目錄下會(huì)有debug符號(hào)文件),調(diào)試器能夠很好地解析這種文件格式

Child-SP          RetAddr           Call Site 00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa 00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110 00000000`09cbeaa0 00000000`00bc4575 sqlservr+0x1c99e 00000000`09cbed40 00000000`00bc3ea8 sqlservr+0x4575 00000000`09cbed80 00000000`00bdcfad sqlservr+0x3ea8 00000000`09cbf370 00000000`01139d9c sqlservr+0x1cfad 00000000`09cbf430 00000000`032b34c7 sqlservr+0x579d9c 00000000`09cbf650 00000000`00bd2abb sqlservr!TlsGetValueForMsxmlSQL+0x4706d7 00000000`09cbf6c0 00000000`00bd0fda sqlservr+0x12abb 00000000`09cbf7e0 00000000`00bd2665 sqlservr+0x10fda 00000000`09cbf870 00000000`0117abb0 sqlservr+0x12665 00000000`09cbf8e0 00000000`0117c4b0 sqlservr+0x5babb0 00000000`09cbf9a0 00000000`0117a060 sqlservr+0x5bc4b0 00000000`09cbf9d0 00000000`0117a9ef sqlservr+0x5ba060 00000000`09cbfa60 00000000`734937d7 sqlservr+0x5ba9ef 00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47 00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104 00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd 00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21

上面顯示出我們的模塊,sqlservr.exe 和正在執(zhí)行的代碼在地址空間里的位移,但是我們不知道具體的函數(shù)名,如果有符號(hào)映射的幫助(symbols mapped),我們可以獲取到更有意義輸出

Child-SP          RetAddr           Call Site 00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa 00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110 00000000`09cbeaa0 00000000`00bc4575 sqlservr!SOS_Scheduler::SwitchContext+0x84e 00000000`09cbed40 00000000`00bc3ea8 sqlservr!SOS_Scheduler::SuspendNonPReemptive+0xc5 00000000`09cbed80 00000000`00bdcfad sqlservr!EventInternal<Spinlock<149,1,0> >::Wait+0x428 00000000`09cbf370 00000000`01139d9c sqlservr!ResQueueBase::Dequeue+0x19d 00000000`09cbf430 00000000`032b34c7 sqlservr!CheckpointLoop+0x1aa 00000000`09cbf650 00000000`00bd2abb sqlservr!ckptproc+0x47 00000000`09cbf6c0 00000000`00bd0fda sqlservr!SOS_Task::Param::Execute+0x11b00000000`09cbf7e0 00000000`00bd2665 sqlservr!SOS_Scheduler::RunTask+0xca 00000000`09cbf870 00000000`0117abb0 sqlservr!SOS_Scheduler::ProcessTasks+0x95 00000000`09cbf8e0 00000000`0117c4b0 sqlservr!SchedulerManager::WorkerEntryPoint+0x110 00000000`09cbf9a0 00000000`0117a060 sqlservr!SystemThread::RunWorker+0x60 00000000`09cbf9d0 00000000`0117a9ef sqlservr!SystemThreadDispatcher::ProcessWorker+0x12c 00000000`09cbfa60 00000000`734937d7 sqlservr!SchedulerManager::ThreadEntryPoint+0x12f 00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47 00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104 00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd 00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21

從上面的輸出的函數(shù)名我們可以看到Checkpoint 線程

上面看到worker thread在CHECKPOINT_QUEUE 隊(duì)列里面等待CHECKPOINT 命令

大家可以看到加上符號(hào)文件之后,調(diào)試器會(huì)在stack trace相應(yīng)的位置進(jìn)行轉(zhuǎn)換,例如在模塊名那里加上模塊名,在函數(shù)名那里加上函數(shù)名

<module_name>!<function call>or<module_name>!<class_name>::<method/function call>


設(shè)置符號(hào)路徑

設(shè)置符號(hào)路徑的作用是使調(diào)試器可以找到符號(hào)文件的位置并進(jìn)行加載在調(diào)試的時(shí)候

簡(jiǎn)單介紹一下符號(hào)路徑和公私有符號(hào)文件

私有符號(hào)文件:包含了調(diào)試會(huì)話中需要的所有符號(hào)信息(只對(duì)微軟內(nèi)部開放,微軟私有財(cái)產(chǎn))公有符號(hào)文件:只是有選擇地包含一些符號(hào)信息(對(duì)所有人開放)

符號(hào)信息隸屬于指定的模塊,只有調(diào)試器需要用到某個(gè)模塊時(shí),它的符號(hào)信息才有被加載和分析的必要

要在調(diào)試器中使用符號(hào),我們必須首先告訴調(diào)試器這些符號(hào)文件的位置,也就是設(shè)置符號(hào)路徑。符號(hào)路徑可以是本地文件夾路徑、可訪問的UNC路徑、或者是符號(hào)服務(wù)器路徑

符號(hào)服務(wù)器:在調(diào)試過程中,需要涉及成千上萬個(gè)符號(hào)文件,以及同一個(gè)符號(hào)文件存在不同平臺(tái)下的不同符號(hào)文件版本的時(shí)候。

手動(dòng)設(shè)置符號(hào)路徑肯定是不現(xiàn)實(shí)的,于是引入了符號(hào)服務(wù)器的概念

符號(hào)服務(wù)器有一套命名規(guī)則,使得調(diào)試軟件能夠正確找到需要的符號(hào)文件。一般來說,符號(hào)服務(wù)器比較大,都是共用的,放在遠(yuǎn)程主機(jī)上。

為了降低網(wǎng)絡(luò)訪問的成本,又引入了符號(hào)緩存的概念,即將從服務(wù)器上下載到的符號(hào)文件,保存在本地緩存中,以后調(diào)試器需要符號(hào)文件的時(shí)候,先從緩存中尋找,找不到的時(shí)候再到服務(wù)器上下載

  1、設(shè)置符號(hào)路徑

  設(shè)置符號(hào)路徑的語法如下:

.sympath [+] [路徑]

  如要覆蓋原來的路徑設(shè)置,使用新路徑即可:

.sympath <新路徑>

  要在原有路徑的基礎(chǔ)上添加一個(gè)新路徑,可使用:

.sympath+ <新增路徑>

  如果不帶參數(shù),那么輸出是當(dāng)前設(shè)置的符號(hào)路徑:

0:000> .sympathSymbol search path is: <empty>  //尚未設(shè)置符號(hào)路徑

  假如在調(diào)試時(shí),我知道需要的符號(hào)文件位于一下文件夾"D:/MyPdb“。

0:000> .sympath D:/MyPdb  //覆蓋原有符號(hào)路徑Symbol search path is: D:/MyPdbExpanded Symbol search path is: d:/mypdb

  此時(shí)調(diào)試器將記錄上面新的符號(hào)路徑,但并不會(huì)從這個(gè)路徑中加載任何符號(hào),要指示調(diào)試器加載符號(hào),可以使用元命令reload。

這個(gè)命令能枚舉出進(jìn)程地址空間中所有已加載的模塊,并且嘗試找出與各個(gè)模塊相關(guān)的符號(hào)文件。

0:000> .reloadReloading current modules.....

  如果調(diào)試器在指定目錄無法找到文件,那么它會(huì)輸出錯(cuò)誤提示:

*** ERROR:Symbol file could not be found. Defaulted to export symbols for xxx.dll

  當(dāng)沒有設(shè)置本地緩存路徑時(shí),那么調(diào)試器將使用調(diào)試軟件的安裝路徑下的sym文件夾。

  要特別注意的是,使用.sympath改變或新增符號(hào)路徑后,符號(hào)文件并不會(huì)自動(dòng)更新,應(yīng)再執(zhí)行.reload命令以進(jìn)行更新。

  

  2、符號(hào)服務(wù)器與符號(hào)緩存

  設(shè)置符號(hào)服務(wù)器的基本語法是:

SRV*[符號(hào)緩存]*服務(wù)器地址

  語法有SRV引導(dǎo),符號(hào)緩存和服務(wù)器地址的前面各有一個(gè)星號(hào)引導(dǎo)。

  此外,我們總是應(yīng)該把微軟的公用符號(hào)庫加入到我們的符號(hào)路徑中:

.sympath+ srv*<緩存地址>*http://msdl.microsoft.com/download/symbols

  這是一臺(tái)微軟對(duì)外公開的服務(wù)器,使用http地址訪問,不是所有人都能牢記這個(gè)網(wǎng)址,所以最好的辦法就是使用.symfix命令(自動(dòng)記憶了上面

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 明溪县| 色达县| 子洲县| 唐海县| 红安县| 本溪| 阜城县| 旺苍县| 桓台县| 康马县| 安新县| 金门县| 郓城县| 平原县| 东山县| 朝阳县| 东阿县| 达孜县| 罗田县| 宾川县| 茌平县| 静宁县| 宁德市| 舒兰市| 江安县| 乐平市| 内江市| 新宁县| 武功县| 杭锦旗| 藁城市| 阿荣旗| 察隅县| 雅安市| 襄樊市| 乌鲁木齐县| 改则县| 长宁区| 汝州市| 奉化市| 宜春市|