青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

focus on linux, c/c++, lua

Walking the callstack [譯文 part2]

遍歷當(dāng)前線程的callstack

x86的系統(tǒng)上(XP之前),是沒有一個直接的API用來獲得當(dāng)前線程的上下文的。當(dāng)時提倡的做法是在捕獲系統(tǒng)異常中來獲得。現(xiàn)在在我們的代碼中,我們實現(xiàn)了有效的獲取上下文的方法。默認(rèn)的情況下,我們是通過內(nèi)聯(lián)匯編代碼來獲取EIP,ESPEBP的值。如果你想使用我剛才提到的捕獲異常的方法來實現(xiàn)的話,那你就需要定義一個CURRENT_THREAD_VIA_EXCEPTION這樣的宏。但是我們應(yīng)該意識到,其實GET_CURRENT_CONTEXT也是一個宏,內(nèi)部也是使用了捕捉異常的原理。我們的函數(shù)都必須要能包含這些宏的聲明。

XP開始以及在x64IA64平臺上,目前已經(jīng)有API來獲得當(dāng)前線程的上下文,就是RtlCaptureContext.

演示代碼7

StackWalker sw;

sw.ShowCallstack();

在同一個進程內(nèi)遍歷其他線程的callstack(略)

遍歷另一個進程內(nèi)的某線程callstack(略)

(譯者注:由于時間原因,上述兩部分的翻譯暫時省略了,內(nèi)容也比較簡單,只是調(diào)用了StackWalker的不同構(gòu)造函數(shù))

重用StackWalk的實例

重用StackWalk的實例是沒有任何問題的,只要你想在同一個進程內(nèi)遍歷callstack。如果你重復(fù)多次用到callstack的遍歷,我強烈你推薦重用一個實例。原因很簡單:當(dāng)你創(chuàng)建一個新的實例的時候,symbol文件就要被重新加載一次,這個是非常耗時的。而且多個StackWalk跨線程工作也是不可靠的,因為dbghelp.dll不是線程安全的。綜上,在一個進程中保持只有一個StackWalker實例是最合理的做法。

Symbol的搜索路徑

通常情況下,Symbol的搜索路徑(SymBuildPath SymUseSymSrv)主要是用來搜索這個文件dbghelp.dll。這個路徑通常包含一下目錄:

1, szSymPath是否提供是可選擇的,如果提供的話,那么SymBuildPath會自動生成。在szSymPath中每個路徑之間要用分號“;”來分開。

2, 當(dāng)前工作目錄

3, 可執(zhí)行文件的目錄,如exel

4, _NT_SYMBOL_PATH的環(huán)境變量

5, _NT_ALTERNATE_SYMBOL_PATH的環(huán)境變量

6, SYSTEMROOT的環(huán)境變量

7, SYSTEMROOT\system32的環(huán)境變量

8, MS符號服務(wù)器SRV*%SYSTEMDRIVE%\websymbols*http://msdl.microsoft.com/download/symbols

符號服務(wù)器

如果你想使用MS的公共信號服務(wù)器,你可以選擇安裝windbg(這樣symsrv.dll和最新dbghelp.dll會被自動查詢到),你也可以選擇從網(wǎng)絡(luò)傳輸中獲取這些最新符號,不過推薦前者,這樣就不會因為網(wǎng)絡(luò)故障而出現(xiàn)加載符號失敗。

加載程式和符號

為了能成功遍歷線程的callstackdbghelp.dll要獲得所有被加載模塊的信息。所有你需要通過SymLoadModule64這個API來注冊所有被加載的模塊,在注冊之前,第一步是枚舉出所有的模塊。

win9x之后。利用ToolHelp32_API可以實現(xiàn)這個需求,需要用的API有,CreateToolhelp32SnapShotModule32FirstModule32Next。通常情況下這些API包含在kernel32.dll,但是在win9x的系統(tǒng)上,這些API包含在tlhelp32.dll中,所以在代碼中要做分支判斷。

如果你是在NT4上干活的話,那么使用ToolHelp32-API只是一個夢想。但是你可以使用PSAPI來取而代之。你需要使用到一下APIEnumProcessModules, GetModuleInformation, GetModuleBaseName, GetModuleFileNameEx


遍歷當(dāng)前線程的
callstack

x86的系統(tǒng)上(XP之前),是沒有一個直接的API用來獲得當(dāng)前線程的上下文的。當(dāng)時提倡的做法是在捕獲系統(tǒng)異常中來獲得。現(xiàn)在在我們的代碼中,我們實現(xiàn)了有效的獲取上下文的方法。默認(rèn)的情況下,我們是通過內(nèi)聯(lián)匯編代碼來獲取EIP,ESPEBP的值。如果你想使用我剛才提到的捕獲異常的方法來實現(xiàn)的話,那你就需要定義一個CURRENT_THREAD_VIA_EXCEPTION這樣的宏。但是我們應(yīng)該意識到,其實GET_CURRENT_CONTEXT也是一個宏,內(nèi)部也是使用了捕捉異常的原理。我們的函數(shù)都必須要能包含這些宏的聲明。

XP開始以及在x64IA64平臺上,目前已經(jīng)有API來獲得當(dāng)前線程的上下文,就是RtlCaptureContext.

演示代碼7

StackWalker sw;

sw.ShowCallstack();

在同一個進程內(nèi)遍歷其他線程的callstack(略)

遍歷另一個進程內(nèi)的某線程callstack(略)

(譯者注:由于時間原因,上述兩部分的翻譯暫時省略了,內(nèi)容也比較簡單,只是調(diào)用了StackWalker的不同構(gòu)造函數(shù))

重用StackWalk的實例

重用StackWalk的實例是沒有任何問題的,只要你想在同一個進程內(nèi)遍歷callstack。如果你重復(fù)多次用到callstack的遍歷,我強烈你推薦重用一個實例。原因很簡單:當(dāng)你創(chuàng)建一個新的實例的時候,symbol文件就要被重新加載一次,這個是非常耗時的。而且多個StackWalk跨線程工作也是不可靠的,因為dbghelp.dll不是線程安全的。綜上,在一個進程中保持只有一個StackWalker實例是最合理的做法。

Symbol的搜索路徑

通常情況下,Symbol的搜索路徑(SymBuildPath SymUseSymSrv)主要是用來搜索這個文件dbghelp.dll。這個路徑通常包含一下目錄:

1, szSymPath是否提供是可選擇的,如果提供的話,那么SymBuildPath會自動生成。在szSymPath中每個路徑之間要用分號“;”來分開。

2, 當(dāng)前工作目錄

3, 可執(zhí)行文件的目錄,如exel

4, _NT_SYMBOL_PATH的環(huán)境變量

5, _NT_ALTERNATE_SYMBOL_PATH的環(huán)境變量

6, SYSTEMROOT的環(huán)境變量

7, SYSTEMROOT\system32的環(huán)境變量

8, MS符號服務(wù)器SRV*%SYSTEMDRIVE%\websymbols*http://msdl.microsoft.com/download/symbols

符號服務(wù)器

如果你想使用MS的公共信號服務(wù)器,你可以選擇安裝windbg(這樣symsrv.dll和最新dbghelp.dll會被自動查詢到),你也可以選擇從網(wǎng)絡(luò)傳輸中獲取這些最新符號,不過推薦前者,這樣就不會因為網(wǎng)絡(luò)故障而出現(xiàn)加載符號失敗。

加載程式和符號

為了能成功遍歷線程的callstackdbghelp.dll要獲得所有被加載模塊的信息。所有你需要通過SymLoadModule64這個API來注冊所有被加載的模塊,在注冊之前,第一步是枚舉出所有的模塊。

win9x之后。利用ToolHelp32_API可以實現(xiàn)這個需求,需要用的API有,CreateToolhelp32SnapShotModule32FirstModule32Next。通常情況下這些API包含在kernel32.dll,但是在win9x的系統(tǒng)上,這些API包含在tlhelp32.dll中,所以在代碼中要做分支判斷。

如果你是在NT4上干活的話,那么使用ToolHelp32-API只是一個夢想。但是你可以使用PSAPI來取而代之。你需要使用到一下APIEnumProcessModules, GetModuleInformation, GetModuleBaseName, GetModuleFileNameEx


Dbghelp.dll

下面就來隨便啰嗦幾句dbghelp.dll

1, 首先,在MS,有兩個team在負責(zé)開發(fā)dbghelp.dll,一個是os-team,另一個是debug-team。通常情況下,你會以為windbg提供的dbghelp.dll是最新的版本。但是有個問題就是這兩個小組發(fā)布的dbghelp.dll的版本是不同的。舉個例子來說:xp-sp1dbghelp.dll版本是5.1.2600.11062002-08-29)。但是debug-team發(fā)布的6.0.0017.0版本時間卻是2002-04-31。(譯者注:寒,MS也會犯這種錯誤)。這樣版本的發(fā)布就會有沖突,所以很難通過版本好來確定哪個更好,更有效。

2, Winme/W2k開始,system32目錄下面的dbghelp.dll文件是受保護的。所以如果你想成功遍歷callstack,,最好去下載個最新版本的dbghelp.dll放在你的exe目錄下面。否則在W2k上會導(dǎo)致一個問題,就是,如果你想遍歷一個用VC7+編譯的工程就會出錯。因為VC7+的編譯器生成的PDB格式文件不能被dbghelp.dll識別,這樣你就不會得到有效的callstack信息。總之,保險起見,不要使用 OSdbghelp.dll,去下載最新的dbghelp.dll來使用。(譯者注:我在論壇中看到很多人無法正確遍歷棧,都是dbghelp.dll的版本較老造成的。)

3, V6.5.3.7版本的dbghelp.dll有個bug,或是說StackWalk64函數(shù)的文檔發(fā)生了變化。文檔中描述:

如果STACKFRAME64的兩個成員AddrPCAddrFrame沒有被初始化就作為參數(shù)傳給StackWalk64的話,那么這個函數(shù)在第一次被調(diào)用的時候就會失敗。而且,只有當(dāng)參數(shù)MachineType不是IAMGE_FILE_MACHINE_I386的時候,參數(shù)ContectRecord才要求被初始化。

但是這個是錯誤的。在x86上,當(dāng)你給ContextRecordNULL的時候,并不能獲得到callstack。以我的觀點,這是比較大的文檔改動。現(xiàn)在你既可以通過初始話AddrStack,也可以通過包含EIP,EBP,ESPContextRecord來成功獲取callstack

Stackwalker的操作開關(guān)

你可以按照自己的需求來定義操作開關(guān)

演示代碼7

typedef enum StackWalkOptions

{

    // No addition info will be retrived

    // (only the address is available)

    RetrieveNone = 0,

    // Try to get the symbol-name

    RetrieveSymbol = 1,

    // Try to get the line for this symbol

    RetrieveLine = 2,

    // Try to retrieve the module-infos

    RetrieveModuleInfo = 4,

    // Also retrieve the version for the DLL/EXE

    RetrieveFileVersion = 8,

    // Contains all the abouve

    RetrieveVerbose = 0xF,

    // Generate a "good" symbol-search-path

    SymBuildPath = 0x10,

    // Also use the public Microsoft-Symbol-Server

    SymUseSymSrv = 0x20,

    // Contains all the abouve "Sym"-options

    SymAll = 0x30,

    // Contains all options (default)

    OptionsAll = 0x3F

} StackWalkOptions;

 

使用須知

1, NT/Win9x:這個工程只支持StackWalk64這個API。如果你想在NT4/win9x上使用的話,你需要重新配置dbghelp.dll

2, 當(dāng)前工程在遍歷過程中只支持ANSI名稱符,(譯者注:C++中沒看到過有人用中文命名的函數(shù)名,但java大有人在),當(dāng)然,如果你也可以選擇以unicode的編碼方式來編譯工程來解決中文函數(shù)名的問題。

3, NT4/win9x的平臺上,用“OpenThread”來打開遠程線程是不支持的,如果你想實現(xiàn),請參考Remote Library

4, 遍歷混合模式的callstack(包含managedunmanaged)并不會返回unmanaged的函數(shù)。

posted on 2010-10-20 10:22 zuhd 閱讀(627) 評論(0)  編輯 收藏 引用 所屬分類: c/c++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线综合视频| 亚洲精品免费一二三区| 久久综合影视| 精品动漫3d一区二区三区| 亚洲在线视频| 久久国产精品99国产精| 国产酒店精品激情| 亚洲天堂av综合网| 久久躁日日躁aaaaxxxx| 在线日本欧美| 欧美日韩国产成人在线免费| 99精品热视频只有精品10| 国产精品99久久99久久久二8 | 欧美日韩成人在线视频| 在线亚洲伦理| 欧美黄色aa电影| 性久久久久久| 中国日韩欧美久久久久久久久| 国产精品美女午夜av| 美女国产一区| 午夜激情久久久| 亚洲欧洲在线观看| 久久免费一区| 欧美亚洲网站| 亚洲摸下面视频| 亚洲欧洲三级电影| 136国产福利精品导航网址| 国产一区二区三区的电影 | 亚洲精品中文字| 91久久精品一区| 夜夜嗨一区二区三区| 性欧美暴力猛交另类hd| 蜜臀a∨国产成人精品| 欧美日韩一区二区在线观看| 国内精品免费在线观看| 欧美午夜免费电影| 国产一区二区久久| 欧美一级成年大片在线观看| 中文精品一区二区三区| 国产精品久久久久久久久久久久| 国产精品hd| 国产一区二区三区在线观看免费视频| 国产女主播一区二区三区| 国产日本精品| 在线观看一区视频| 日韩视频国产视频| 在线视频精品一区| 欧美在线你懂的| 国产精品大全| 国产精品综合| 亚洲福利视频在线| 亚洲图片在线观看| 亚洲四色影视在线观看| 久久精视频免费在线久久完整在线看| 久久精品视频免费播放| 亚洲国产精品一区二区第一页 | 99在线精品视频| 欧美在线视频网站| 欧美日韩美女一区二区| 国产亚洲福利一区| 亚洲线精品一区二区三区八戒| 欧美一区二区视频观看视频| 91久久精品国产91久久性色| 欧美一区成人| 国产精品成人观看视频免费| 亚洲大胆av| 久久先锋影音av| 亚洲欧美日韩中文播放| 欧美伦理91| 欧美伊人久久大香线蕉综合69| 久久综合色影院| 午夜精品亚洲| 欧美在线视频观看| 亚洲第一精品影视| 久久免费国产精品1| 亚洲欧美日韩国产中文| 欧美激情一区二区三区不卡| 亚洲三级影院| 欧美电影打屁股sp| 亚洲第一黄色网| 久久久久国产免费免费| 欧美一级片久久久久久久| 国产深夜精品福利| 久久精品国产91精品亚洲| 亚洲中字在线| 国产日韩一区二区| 欧美在线播放高清精品| 先锋影音网一区二区| 精品96久久久久久中文字幕无| 久久亚洲私人国产精品va| 狼狼综合久久久久综合网| 亚洲男女自偷自拍| 久久香蕉精品| 91久久午夜| 99精品久久久| 午夜久久久久久久久久一区二区| 久久中文字幕导航| 国产精品99久久久久久宅男 | 欧美aa国产视频| 亚洲综合欧美| 欧美aaa级| 久久精品99无色码中文字幕| 久久精品网址| 性欧美xxxx大乳国产app| 久久人人爽国产| 久久精品国产96久久久香蕉| 久久综合给合| 久久久久99精品国产片| 欧美吻胸吃奶大尺度电影| 欧美xxxx在线观看| 国产亚洲一区二区在线观看| 亚洲国产视频直播| 亚洲国产综合91精品麻豆| 先锋影音一区二区三区| 亚洲午夜在线观看视频在线| 卡通动漫国产精品| 老司机67194精品线观看| 国产一区二区三区黄| 亚洲欧美日韩区| 欧美一级视频精品观看| 欧美亚洲成人免费| 亚洲无毛电影| 欧美亚洲日本一区| 国产精品一区2区| 亚欧成人在线| 老司机午夜免费精品视频| 亚洲成人直播| 欧美福利视频在线| 一本一本久久a久久精品综合妖精| 日韩午夜激情av| 国产精品v欧美精品∨日韩| 亚洲一区二区欧美| 久久综合激情| 99国产一区| 国产在线精品成人一区二区三区| 久久电影一区| 亚洲国产综合91精品麻豆| 亚洲少妇诱惑| 国产一区二区三区在线观看免费| 久久久999国产| 一区二区三区免费看| 久久久久国内| 亚洲综合视频1区| 1024亚洲| 韩国在线一区| 国产精品高潮在线| 欧美成人免费观看| 性欧美大战久久久久久久久| 亚洲精品永久免费精品| 久久亚洲国产精品日日av夜夜| 亚洲天堂免费在线观看视频| 在线观看91久久久久久| 亚洲日本免费电影| 久久蜜桃精品| 欧美一区成人| 亚洲欧美精品一区| 亚洲影音一区| 亚洲天堂网在线观看| 亚洲精选91| 亚洲精品一区二区三区蜜桃久| 国产婷婷成人久久av免费高清| 欧美色欧美亚洲高清在线视频| 蜜乳av另类精品一区二区| 久久免费视频在线观看| 久久免费国产精品| 99在线精品视频在线观看| 模特精品裸拍一区| 亚洲第一搞黄网站| 欧美成人国产va精品日本一级| 麻豆九一精品爱看视频在线观看免费| 欧美一区影院| 欧美成人免费一级人片100| 欧美成年视频| 日韩午夜激情| 亚洲免费在线播放| 久久这里只精品最新地址| 欧美成人午夜免费视在线看片| 欧美日韩国产黄| 国产欧美视频一区二区三区| 在线观看视频亚洲| 99视频精品在线| 久久精品首页| 久久久久久尹人网香蕉| 性欧美video另类hd性玩具| 亚洲欧美日本在线| 亚洲毛片视频| 国产精品一区视频| 一区二区日韩| 亚洲先锋成人| 国产一区日韩一区| 好看不卡的中文字幕| 国产裸体写真av一区二区| 亚洲欧美日韩精品在线| 亚洲自拍都市欧美小说| 欧美色视频在线| 亚洲欧美日韩直播| 香港久久久电影| 亚洲国产精品精华液2区45| 亚洲激情成人网| 国产精品欧美日韩一区|