av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Vistual Studio原生開(kāi)發(fā)的20條調(diào)試技巧(下)

我的上篇文章《Vistual Studio原生開(kāi)發(fā)的10個(gè)調(diào)試技巧》 引發(fā)了很多人的興趣,所以我決定跟大家分享更多的調(diào)試技巧。接下來(lái)你又能看到一些對(duì)于原生應(yīng)用程序的很有幫助的調(diào)試技巧(接著上一篇文章來(lái)編號(hào))。這些技 巧需要應(yīng)用在Vistual Studio 2005 或者更新的版本中(當(dāng)然也有一些適用于舊版本)。如果你能閱讀本文中推薦的一些相關(guān)文章,就可以知道每一個(gè)技巧的更多信息。

創(chuàng)新互聯(lián)專(zhuān)業(yè)為企業(yè)提供敘州網(wǎng)站建設(shè)、敘州做網(wǎng)站、敘州網(wǎng)站設(shè)計(jì)、敘州網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、敘州企業(yè)網(wǎng)站模板建站服務(wù),10多年敘州做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

  • 11. 數(shù)據(jù)斷點(diǎn)
  • 12. 線程重命名
  • 13. 給指定線程設(shè)置斷點(diǎn)
  • 14.(粗略)估算執(zhí)行時(shí)間
  • 15.  數(shù)字格式化
  • 16. (內(nèi)存)數(shù)據(jù)格式化
  • 17.系統(tǒng)DLL中斷
  • 18.加載符號(hào)表
  • 19.  監(jiān)測(cè)MFC中的內(nèi)存泄漏
  • 20.  調(diào)試ATL

技巧11數(shù)據(jù)斷點(diǎn)

當(dāng)數(shù)據(jù)所在的內(nèi)存位置發(fā)生變化時(shí),可以通知調(diào)試器進(jìn)行中斷,但是每次只能創(chuàng)建4個(gè)字節(jié)這樣的硬件數(shù)據(jù)斷點(diǎn)。數(shù)據(jù)斷點(diǎn)只能在調(diào)試期間添加,可以通過(guò)菜 單(Debug>New Breakpoint>New Data Breakpoint) 或者斷點(diǎn)窗口來(lái)添加。

你可以使用內(nèi)存地址或者地址表達(dá)式。盡管棧上和堆上的值你都可以看到,但是我認(rèn)為當(dāng)堆上的數(shù)值發(fā)生變化時(shí),這個(gè)功能才會(huì)更有用處。它對(duì)于識(shí)別內(nèi)存損壞有很大的幫助。

下面的例子中,指針的值發(fā)生了變化,不再是它所指向?qū)ο蟮闹?。為了找出在什么地方發(fā)生改變的,我在存儲(chǔ)指針值的位置設(shè)置了一個(gè)斷點(diǎn), 即&ptr(注意必須在指針初始化之后)。數(shù)據(jù)發(fā)生變化就意味著有人修改了指針的值,調(diào)試器發(fā)生中斷,我就能找出是哪段代碼引起的改變。

更多閱讀:

1.怎樣查明指針是否損壞內(nèi)存

2.怎樣查明指針在什么地方發(fā)生改變

技巧12線程重命名

在調(diào)試多線程應(yīng)用程序時(shí),線程窗口會(huì)顯示創(chuàng)建了哪些線程以及當(dāng)前正在運(yùn)行的線程。線程越多,想找到你想要的線程就越困難(尤其是當(dāng)一段程序被多個(gè)線程同時(shí)執(zhí)行的時(shí)候,你不能確切地知道哪個(gè)才是當(dāng)前正在執(zhí)行的線程實(shí)例)。

調(diào)試器允許修改線程的名字,可以在線程窗口使用線程的快捷菜單,給線程重命名。

也可以在程序里給線程命名,盡管有點(diǎn)棘手,而且必須在線程啟動(dòng)之后給它命名,否則調(diào)試器會(huì)以默認(rèn)命名規(guī)范將它重新初始化。定義一個(gè)線程,并用下面的函數(shù)重命名該線程。

 
 
 
 
  1. typedef struct tagTHREADNAME_INFO 
  2.     DWORD dwType;        // must be 0x1000 
  3.     LPCSTR szName;       // pointer to name (in same addr space) 
  4.     DWORD dwThreadID;    // thread ID (-1 caller thread) 
  5.     DWORD dwFlags;       // reserved for future use, most be zero 
  6. } THREADNAME_INFO; 
  7.   
  8. void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) 
  9.     THREADNAME_INFO info; 
  10.     info.dwType = 0x1000; 
  11.     info.szName = szThreadName; 
  12.     info.dwThreadID = dwThreadID; 
  13.     info.dwFlags = 0; 
  14.   
  15.     __try 
  16.     { 
  17.         RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info); 
  18.     } 
  19.     __except (EXCEPTION_CONTINUE_EXECUTION) 
  20.     { 
  21.     } 

更多閱讀:

設(shè)置線程名字(非托管)

#p#

技巧13: 給指定線程設(shè)置斷點(diǎn)

 對(duì)于多線程應(yīng)用程序來(lái)說(shuō),另一個(gè)有用的技巧就是給指定的線程,進(jìn)程,甚至是計(jì)算機(jī)中的斷點(diǎn)設(shè)置過(guò)濾.可以通過(guò)斷點(diǎn)的Filter命令來(lái)實(shí)現(xiàn)此功能.

調(diào)試器允許你指定線程名,線程ID,進(jìn)程名,進(jìn)程ID和機(jī)器名的任意組合(使用AND,OR,NOT)來(lái)設(shè)置過(guò)濾。了解怎樣設(shè)置線程名字也使得這項(xiàng)過(guò)濾操作變得更加簡(jiǎn)單。

更多閱讀:

  1. 怎樣指定斷點(diǎn)過(guò)濾器
  2. 設(shè)置斷點(diǎn)過(guò)濾

技巧14: (粗略)估算執(zhí)行時(shí)間

在上一篇文章中,我有寫(xiě)關(guān)于Watch窗口中的偽變量,有一個(gè)沒(méi)提到的是@clk,它用于顯示計(jì)數(shù)器的值,可以粗略地計(jì) 算出兩個(gè)斷點(diǎn)之間的代碼的執(zhí)行時(shí)間,單位是微秒(μS)。但是,千萬(wàn)不要用這個(gè)方法來(lái)分析程序的執(zhí)行效率,應(yīng)該使用Visual Studio 分析工具或者性能計(jì)時(shí)器來(lái)分析。

可以在Watch 窗口或者即時(shí)窗口添加@clk=0來(lái)完成對(duì)計(jì)時(shí)器的重置。因此要想估算執(zhí)行一段代碼需要多長(zhǎng)時(shí)間,可以按照下面的步驟來(lái)操作:

  1. 在代碼塊的開(kāi)始位置設(shè)置斷點(diǎn)
  2. 在代碼塊的結(jié)束位置設(shè)置斷點(diǎn)
    1. 在Watch窗口添加 @clk
    2. 程序進(jìn)入到第一個(gè)斷點(diǎn)時(shí),在即時(shí)窗口輸入@clk=0
    3. 運(yùn)行程序直到執(zhí)行進(jìn)入代碼塊末尾的斷點(diǎn),查看Watch窗口 @clk的值。

注意網(wǎng)上有一些技巧說(shuō)在Watch窗口添加兩個(gè)表達(dá)式:@clk和@clk=0,需要在每次執(zhí)行斷點(diǎn)的時(shí)候都要重置計(jì)時(shí)器。這種用法只適用于Visual Studio的老版本,在VS2005及以上版本不再適用。

更多閱讀:

 調(diào)試技巧-@CLK

技巧15:數(shù)字格式化

當(dāng)你在Watch或者Quick Watch窗口查看變量時(shí), 這些值是以默認(rèn)的預(yù)定義可視化形式顯示的。而對(duì)于數(shù)字,則是根據(jù)數(shù)據(jù)類(lèi)型(integer, float, double),用十進(jìn)制形式顯示的。但是你可以使用調(diào)試器把數(shù)字用不同的類(lèi)型或者進(jìn)制數(shù)顯示出來(lái)。

想要改變顯示類(lèi)型可在變量前加以下前綴:

  1. by –unsigned char (又稱為unsigned byte)
  2. wo –unsigned shot(又稱為 unsigned word)
  3. dw – unsigned long(又稱為 unsigned double word) 

要改變顯示的進(jìn)制數(shù)在變量前加下列前綴:

  1. d 或者 i– 有符號(hào)十進(jìn)制數(shù)
  2. u – 無(wú)符號(hào)十進(jìn)制數(shù)
  3. o -  無(wú)符號(hào)八進(jìn)制數(shù)
  4. x – 小寫(xiě)十六進(jìn)制數(shù)
  5. X – 大寫(xiě)十六進(jìn)制數(shù)

更多閱讀:

C++ 調(diào)試技巧

#p#

技巧16:(內(nèi)存數(shù)據(jù))格式化

除了數(shù)字,調(diào)試器還可以在Watch窗口顯示格式化的內(nèi)存數(shù)據(jù),最多64 bytes。 你可以使用在表達(dá)式(變量或內(nèi)存地址)后添加下列說(shuō)明符作為后綴來(lái)格式化數(shù)據(jù):

  1. mb 或者 m – 十六進(jìn)制顯示的16字節(jié)數(shù)據(jù),后跟16個(gè)ASCII 字符
  2. mw – 8 words
  3. md – 4 double words
  4. mq -  2 quad-words
  5. ma – 64個(gè)ASCII字符
  6. mu – 2字節(jié)的UNICODE字符

更多閱讀:

  1. C++中的格式說(shuō)明符
  2. Developer Studio的調(diào)試技巧

技巧17: 系統(tǒng)DLL的中斷

 有時(shí)候在DLL中的函數(shù)被調(diào)用時(shí)進(jìn)行中斷是很有用的,像系統(tǒng)DLL(比如 Kernel32.dll 或者user32.dll).實(shí)現(xiàn)此中斷,需要使用本機(jī)調(diào)試器提供的上下文運(yùn)算符.你可以設(shè)定斷點(diǎn)位置,變量名或者表達(dá)式:

 1.{[函數(shù)],[源碼],[模塊]}位置

 2. [函數(shù)],[源碼],[模塊]}變量名

 3. [函數(shù)],[源碼],[模塊]}表達(dá)式

花括號(hào)里可以是函數(shù)名,源代碼和模塊的任意組合,但是逗號(hào)不能省略.

我們假設(shè)想要在CreateThread函數(shù)被調(diào)用時(shí)發(fā)生中斷,這個(gè)函數(shù)是從kernel32.dll中導(dǎo)出的,所以上下文運(yùn)算符應(yīng)該為:  {,,kernel32.dll}CreateThread. 然而,這樣并不可行,因?yàn)樯舷挛倪\(yùn)算符需要CreatThread的修飾符,可以使用DBH.exe來(lái)獲取一個(gè)特定函數(shù)的修飾符。

下面就是如何得到CreateThread函數(shù)的修飾符的:

 
 
 
 
  1. C:\Program Files (x86)\Debugging Tools for Windows (x86)>dbh.exe -s:srv*C:\Symbo 
  2. ls*http://msdl.microsoft.com/Download/Symbols -d C:\Windows\SysWOW64\kernel32.dl 
  3. l enum *CreateThread* 
  4. Symbol Search Path: srv*C:\Symbols*http://msdl.microsoft.com/Download/Symbols 
  5.   
  6.  index            address     name 
  7.      1            10b4f65 :   _BaseCreateThreadPoolThread@12 
  8.      2            102e6b7 :   _CreateThreadpoolWork@12 
  9.      3            103234c :   _CreateThreadpoolStub@4 
  10.      4            1011ea8 :   _CreateThreadStub@24 
  11.      5            1019d40 :   _NtWow64CsrBasepCreateThread@12 
  12.      6            1019464 :   ??_C@_0BC@PKLIFPAJ@SHCreateThreadRef?$AA@ 
  13.      7            107309c :   ??_C@_0BD@CIEDBPNA@TF_CreateThreadMgr?$AA@ 
  14.      8            102ce87 :   _CreateThreadpoolCleanupGroupStub@0 
  15.      9            1038fe3 :   _CreateThreadpoolIoStub@16 
  16.      a            102e6f0 :   _CreateThreadpoolTimer@12 
  17.      b            102e759 :   _CreateThreadpoolWaitStub@12 
  18.      c            102ce8e :   _CreateThreadpoolCleanupGroup@0 
  19.      d            102e6e3 :   _CreateThreadpoolTimerStub@12 
  20.      e            1038ff0 :   _CreateThreadpoolIo@16 
  21.      f            102e766 :   _CreateThreadpoolWait@12 
  22.     10            102e6aa :   _CreateThreadpoolWorkStub@12 
  23.     11            1032359 :   _CreateThreadpool@4 

看上去實(shí)際名字應(yīng)該是_CreateThreadStub@24,這樣我們就可以創(chuàng)建斷點(diǎn),{,,kernel32.dll}_CreateThreadStub@24。

運(yùn)行程序,發(fā)生中斷時(shí)會(huì)有消息提示斷點(diǎn)處無(wú)相關(guān)源代碼,直接忽略它。

使用調(diào)用棧窗口查看調(diào)用該函數(shù)的代碼。

更多閱讀:

1.  在Visual Studio 2010中,沒(méi)有源代碼如何設(shè)置斷點(diǎn)

2.  上下文運(yùn)算符(C/C++語(yǔ)言表達(dá)式)

3.  怎樣給函數(shù)設(shè)置斷點(diǎn)

#p#

技巧18:加載符號(hào)表

在調(diào)試程序的時(shí)候,調(diào)用棧窗口不會(huì)顯示完整的調(diào)用棧,跳過(guò)了系統(tǒng)DLL(比如kernel32.dll 和 user32.dll)的信息。

可以通過(guò)加載這些DLL的符號(hào)表來(lái)獲得完整的調(diào)用棧信息,直接在調(diào)用棧窗口使用快捷菜單就能完成。你可以從預(yù)先指定的符號(hào)路徑或者微軟的符號(hào)服務(wù)器(如果是系統(tǒng)DLL)來(lái)下載符號(hào)。符號(hào)下載完成后,直接導(dǎo)入到調(diào)試器,調(diào)用棧就會(huì)得到更新。

這些符合也可以從組件Modules窗口導(dǎo)入。

一旦下載完成,符號(hào)會(huì)保存在緩存中,可以在Tools>Options>Debugging>Symbols中配置。

技巧19:監(jiān)測(cè)MFC中的內(nèi)存泄漏

如果你想要在MFC應(yīng)用程序中檢測(cè)內(nèi)存泄漏,需要使用宏DEBUG_NEW來(lái)重新定new運(yùn)算符,這是new運(yùn)算符的修改版本,記錄了每個(gè)對(duì)象內(nèi)存分配的文件名和行號(hào).在發(fā)行版中DEBUG_NEW會(huì)解析成new運(yùn)算符.

向?qū)傻腗FC源文件在#includes后包含了下面的預(yù)處理指令:

 
 
 
 
  1. #ifdef _DEBUG 
  2. #define new DEBUG_NEW 
  3. #endif 

這就是怎樣重新定義new運(yùn)算符的。

然而,很多STL頭文件和重新定義的new運(yùn)算符和版本不兼容.如果你重新定義了new運(yùn)算符后,又包含 了,,,等頭文件的話,就會(huì)出現(xiàn)下面的錯(cuò)誤 (以為例):

 
 
 
 
  1. 1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(43) : error C2665: 'operator new' : none of the 5 overloads could convert all the argument types 
  2. 1>        c:\program files\microsoft visual studio 9.0\vc\include\new.h(85): could be 'void *operator new(size_t,const std::nothrow_t &) throw()' 
  3. 1>        c:\program files\microsoft visual studio 9.0\vc\include\new.h(93): or       'void *operator new(size_t,void *)' 
  4. 1>        while trying to match the argument list '(const char [70], int)' 
  5. 1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(145) : see reference to function template instantiation '_Ty *std::_Allocate(size_t,_Ty *)' being compiled 
  6. 1>        with 
  7. 1>        [ 
  8. 1>            _Ty=char 
  9. 1>        ] 
  10. 1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(144) : while compiling class template member function 'char *std::allocator<_Ty>::allocate(std::allocator<_Ty>::size_type)' 
  11. 1>        with 
  12. 1>        [ 
  13. 1>            _Ty=char 
  14. 1>        ] 
  15. 1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xstring(2216) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled 
  16. 1>        with 
  17. 1>        [ 
  18. 1>            _Ty=char 
  19. 1>        ] 

解決辦法就是總是把包含這些STL頭文件放在重新定義new運(yùn)算符之前.

更多閱讀:

 DEBUG_NEW

技巧20: 調(diào)試ATL

在開(kāi)發(fā)ATL COM組件時(shí),你可以在調(diào)試器觀察COM對(duì)象的QueryInterface,AddRef和Release的調(diào)用情況.默認(rèn)情況下并不支持這些,但是你 只要在預(yù)處理定義或者預(yù)編譯頭文件時(shí)定義兩個(gè)宏,宏定義好之后,關(guān)于這些函數(shù)的調(diào)用信息就會(huì)顯示在output窗口.

這兩個(gè)宏如下:

  1. _ATL_DEBUG_QI: 顯示你定義的對(duì)象里每一個(gè)被查詢的接口的名字,必須在atlcom.h被包含之前定義.
  2. _ATL_DEBUG_INTERFACES: 在每次AddRef 或者Release被調(diào)用時(shí),顯示接口的當(dāng)前引用計(jì)數(shù)以及對(duì)應(yīng)的類(lèi)名和接口名,必須在atlbase.h被包含之前定義.

更多閱讀:

  1. 調(diào)試技巧
  2. ATL調(diào)試技巧
  3. _ATL_DEBUG_INTERFACES是如何工作的?

結(jié)束語(yǔ)

盡管這兩篇文章并不是包含了所有的調(diào)試技巧,但是足以幫你解決原生開(kāi)發(fā)中調(diào)試時(shí)遇到的大多數(shù)問(wèn)題。


當(dāng)前題目:Vistual Studio原生開(kāi)發(fā)的20條調(diào)試技巧(下)
網(wǎng)頁(yè)鏈接:http://uogjgqi.cn/article/dghhgoi.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流