日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Windbg教程-调试非托管程序的基本命令上

發(fā)布時間:2024/4/11 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windbg教程-调试非托管程序的基本命令上 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Windbg是跟visual studio差不多的一個調(diào)試器,可以用來調(diào)試非托管程序(native application),也可以調(diào)試托管程序(managed application)。它比VS強(qiáng)的地方是你可以使用它來調(diào)試Windows操作系統(tǒng),因此它也被叫做kernel mode debugger,同樣為kernel mode debugger的調(diào)試器還有隨著windbg一起安裝的kd.exe(只不過這是一個命令行工具而已)。然而它在調(diào)試托管程序方面會比VS難用很多,當(dāng)然如果你想看.NET程序的CLR內(nèi)部結(jié)構(gòu),例如內(nèi)存相關(guān)的信息的話,使用windbg還是可以的。

WindbgVS在調(diào)試方面最大的區(qū)別是,Windbg是采用命令驅(qū)動,而VS是采用良好的用戶界面(UI)驅(qū)動。粗看起來,好像windbg是可以通過類似批處理的方式來實(shí)現(xiàn)一些調(diào)試步驟自動化(的確是這樣的,會在后續(xù)的文章中講到),可能你會感覺windbg功能會比VS強(qiáng)一些。實(shí)際上VS也提供了宏支持,你可以編寫宏來控制VS的調(diào)試過程請參考我以前的文章Visual Studio調(diào)試之?dāng)帱c(diǎn)技巧篇

本篇文章里,以下面這個簡單的程序?yàn)槔?#xff0c;我介紹一些在windbg中,調(diào)試托管程序常用的命令:

Nativedebug.cpp

?

#include?"stdafx.h"

#include?<tchar.h>

?

void?Usage()

{

#ifdef?_UNICODE

?????????????????? wprintf(L"[Usage]: nativedebug.exe <digital numbers>\n");

#else

?????????????????? printf("[Usage]: nativedebug.exe <digital numbers>\n");

#endif

}

?

int?_tmain(int?argc, _TCHAR* argv[])

{

?????????int?result = 0;

?????????if?( argc != 2 )

???????? {

?????????????????? Usage();

???????????????????return?-1;

???????? }

?

???????? result = _ttol(argv[1]);

#ifdef?_UNICODE

???????? wprintf(L"%s * %s = %d\n", argv[1], argv[1], result * result);

???????? wprintf(L"Press any key to exit ...\n");

???????? _getwch();

#else

???????? printf("%s * %s = %d\n", result * result);

???????? printf("Press any key to exit ...\n");

???????? _getch();

#endif

?

?????????return?0;

}

?

編譯好了以后,運(yùn)行windbg.exe,點(diǎn)擊菜單中的“File-Open Executable”,在彈出的對話框中選擇nativedebug.exe。你應(yīng)該可以看到類似下面的輸出,我使用綠色的字符注釋了各行輸出的含義:

#

#?注意黃色高亮的字體,它說明這個調(diào)試器是32位的調(diào)試器,只能調(diào)試32位的程序,

#?如果你需要調(diào)試x64或者IA 64的程序,需要運(yùn)行對應(yīng)的調(diào)試器。

#

Microsoft (R) Windows Debugger Version 6.10.0003.233?X86

Copyright (c) Microsoft Corporation. All rights reserved.

#

#?這一行注明了被調(diào)試程序的命令行

#

CommandLine: E:\臨時文檔\Windbg教程\nativedebug\Debug\nativedebug.exe

#

#?下面這幾行說明當(dāng)前沒有設(shè)置好符號文件搜索路徑,符號文件在調(diào)試中比源文件

#?還重要,關(guān)于符號文件的說明和其重要性請參考我的另外一篇文章

# ????????????????????Visual Studio調(diào)試之符號文件

#

Symbol search path is: *** Invalid ***

****************************************************************************

* Symbol loading may be unreliable without a symbol search path.?????????? *

* Use .symfix to have the debugger choose a symbol path.?????????????????? *

* After setting your symbol path, use .reload to refresh symbol locations. *

****************************************************************************

#

#?可執(zhí)行文件搜索路徑告訴了windbg在哪里搜索可執(zhí)行文件(也就是.exe.dll文件)

#?大部分情況下,windbg知道怎樣找到可執(zhí)行文件--從程序的啟動目錄,從PATH環(huán)境

#?變量里面,從system32文件夾里面等等。因此大部分情況下,你不需要設(shè)置這個變量

#?然而在少數(shù)情況下,你需要使用.exepath設(shè)置它。請參看windbg幫助里面的.exepath

#?的說明來了解。一種少數(shù)情況基本上我們用不到是內(nèi)核模式的調(diào)試,另外一種情況

#?是在調(diào)試用戶模式(user modemini dump文件的時候需要指明。

#

Executable search path is:

#

# ModLoad:?指明了當(dāng)前程序加載的其所依賴的?dll文件,以及它們加載的地址。順便

#?說一句,windbg有的時候會使用這些信息來將堆棧轉(zhuǎn)換到對應(yīng)的函數(shù)上去。

#

ModLoad: 00950000 0096b000?? nativedebug.exe

ModLoad: 77d80000 77f00000?? ntdll.dll

ModLoad: 76070000 76170000?? C:\Windows\syswow64\kernel32.dll

ModLoad: 77670000 776b4000?? C:\Windows\syswow64\KERNELBASE.dll

ModLoad: 6ed80000 6eea4000??C:\Windows\WinSxS\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_2a4cbfc25558bcd3\MSVCR90D.dll

#

#?下面這一行說明了當(dāng)前是什么異常導(dǎo)致程序中斷執(zhí)行,是的?,雖然我們剛剛啟動被

#?調(diào)試的程序,的確是一個異常斷點(diǎn)異常導(dǎo)致程序中斷執(zhí)行。至于原因請參看我的

#?另外一篇文章:

#?????????????????Visual Studio調(diào)試之?dāng)帱c(diǎn)基礎(chǔ)篇

#?另外,下面一行中,第一個括號里面的是當(dāng)前的線程ID,第二個括號指明了當(dāng)前的異常

#?是第一次機(jī)會處理,還是第二次機(jī)會處理。First chance的含義請參看我的這篇文章:

#??????????????????Visual Studio調(diào)試之避免單步跟蹤調(diào)試模式

(ec4.d7c): Break instruction exception - code 80000003 (first chance)

#

#?當(dāng)前CPU中各個寄存器的值

#

eax=00000000 ebx=00000000 ecx=f2260000 edx=0016ddd8 esi=fffffffe edi=77da3bdc

eip=77e207ff esp=002df598 ebp=002df5c4 iopl=0???????? nv up ei pl zr na pe nc

cs=0023?ss=002b?ds=002b?es=002b?fs=0053?gs=002b????????????efl=00000246

#

#?沒有symbol,所以在調(diào)試的時候比較麻煩,另外export symbol的含義在后一篇文章

#?中講

#

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

#

#?當(dāng)前中斷時,程序正在執(zhí)行的函數(shù),以及其位置。

#

ntdll!LdrVerifyImageMatchesChecksum+0x6ce:

#

#?當(dāng)前執(zhí)行的指令(或者是下一條要執(zhí)行的指令)。

#

77e207ff cc????????????? int???? 3

?

WindbgVS不同的地方是,windbg在啟動程序后,執(zhí)行main函數(shù)之前,就中斷了,而VS卻是直接執(zhí)行,原因是VS是一個整合的平臺,你可以先在源代碼里面設(shè)置好斷點(diǎn),然后VS從源代碼編譯完程序后,啟動程序之前自動就可以把斷點(diǎn)設(shè)置好。而windbg只是一個調(diào)試器,所以它需要給程序員設(shè)置斷點(diǎn)的機(jī)會,實(shí)際上所有的調(diào)試器的使用模式都是類似的。

 因?yàn)闆]有符號文件,不好調(diào)試,所以需要先加載符號文件。Windbg知道幾個符號文件搜索路徑(symbol path)――就是微軟的公開符號文件服務(wù)器,如果你想查看你的程序在運(yùn)行過程中使用了哪些windowsAPI和函數(shù)的話,可以使用它。執(zhí)行下面的命令來使用這個文件服務(wù)器(不要忽略了前面的點(diǎn)號):

.symfix

上面的命令自動將symbol path設(shè)置為微軟的公開符號文件服務(wù)器地址,如果你在微軟內(nèi)部混過,你會發(fā)現(xiàn)這個命令設(shè)置的路徑有點(diǎn)不同,噓……。

Sympath可以設(shè)置和查看symbol的路徑,執(zhí)行下面這個命令來查看最新的符號文件搜索路徑:

.sympath

#

#?輸出結(jié)果

#

Symbol search path is: SRV**http://msdl.microsoft.com/download/symbols

?

設(shè)置好符號文件搜索路徑以后,接下來每次加載新的可執(zhí)行(.exe或者.dll)文件,windbg都會先在這些路徑里面搜索它的符號文件,但是對于已經(jīng)加載了的可執(zhí)行文件,例如ntdll.dllkernel32.dll,我們需要手動重新加載,使用下面的命令來加載:

.reload

#

#?輸出結(jié)果

#

Reloading current modules

.....

?

這個時候,點(diǎn)擊windbg菜單里面的“View”-“Call Stack”,就可以看到堆棧了。因?yàn)槲覀冞€用到了MS CRT里面的函數(shù),即atoi,所以我們還需要VCRT的符號文件。幸運(yùn)的是,VS自帶了VCRT的私有符號文件,這樣我們用下面的命令將這個符號文件的文件夾路徑添加到windbg的符號文件搜索路徑列表里面來,注意后面的加號,如果不寫加號,就說明將搜索路徑完全替換成新的:

.sympath+ C:\Windows\symbols\dll

#

#?輸出結(jié)果

#

Symbol search path is: SRV**http://msdl.microsoft.com/download/symbols;C:\Windows\symbols\dll

執(zhí)行下面的命令看一下加載的結(jié)果(注意前面沒有點(diǎn)號):

lm

#

#?輸出結(jié)果

#

start??? end????????module name

00b60000 00b7b000?? nativedebug?? (deferred)????????????

6fef0000 70014000?? MSVCR90D?? (private pdb symbols)?D:\Debuggers\sym\msvcr90d.i386.pdb\EBEA784C96244F1E8F8D35E0391C898D1\msvcr90d.i386.pdb

76070000 76170000?? kernel32?? (deferred)????????????

77670000 776b4000?? KERNELBASE?? (deferred)????????????

77d80000 77f00000?? ntdll????? (pdb symbols)?????????D:\Debuggers\sym\wntdll.pdb\E06BEA155E9748BEA818E2D0DD2FED952\wntdll.pdb

上面的輸出結(jié)果會在后文講到,至于如何設(shè)置斷點(diǎn),以及在命令行里面查看堆棧,在后面講――寫文章還是蠻辛苦的。

總結(jié)

以上是生活随笔為你收集整理的Windbg教程-调试非托管程序的基本命令上的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。