• <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>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            VC調試器高級應用----高級斷點篇

            Posted on 2011-08-12 23:37 RTY 閱讀(543) 評論(0)  編輯 收藏 引用 所屬分類: C/C++Windows
            VC調試器高級應用----高級斷點篇

            VC調試器高級應用----高級斷點篇

            .高級斷點語法  
             
            高級斷點語法由兩部分組成:1.上下文部分.2.位置,表達式,變量或Windows消息條件

            用函數,源文件和二進制模塊來指定上下文,上下文的表示方法

            {[函數],[源文件],[二進制模塊]}   

            必須指定唯一的,足夠的上下文信息才能獲取斷點位置.如在TEST.CPP20行設一位置斷點,語法為:{,TEST.CPP,}.20,A.DLLB.DLL都使用了該行,又只想在B.DLL的調用中觸發,則必須使用:{,TEST.CPP,B.DLL}.20. 

            VC調試器中可直接輸入上下文語法:Breakpoints對話框的Location選項卡BreakAt編輯框中.更容易的方法是使用BreatAt框右的箭頭打開菜單,選擇Advanced,然后在Context框中輸入斷點的相應信息

            如想在一個絕對地址上中斷,直接在BreakAt框中輸入地址就行

            .任何函數上快速中斷  
             
            將函數名輸入BreadAt框中.如果是C++代碼,同時還需要類限定符.支持重載了的函數,調試器會列出所有滿足條件的函數供選擇,如輸入時提供足夠的信息,完全可略過選擇過程.如輸入:"CString::operator=(const  char  *)"可唯一確定要中斷的函數.  
             
            .在系統或DLL輸出的函數中設置斷點  
             
            在程序中從DLL輸入的函數中設置一個斷點可能是毫無作用的,調試器需要知道在何處可以找到該函數上下文信息,同時,函數名取決于是否加載了DLL的符號.只有在W2K以上版本中才能在系統DLL中設置斷點--原因在于其它系統沒有提供邊寫入邊復制保護的功能,若一定要啟用這種方法,必須要有COFF(Common  Object  File  Format),并在調試器中輸出啟動的裝載----Options對話框的Debug,Load  COFF  &  Exports選中

            VC調試器用分級的符號信息法,完整的符號的級別高于不太完整的.PDB(Program  Database)文件具有所有可能的源碼行,函數,變量和類型信息,優先級便高于COFF/DBG文件,后者只有公用函數符號,COFF/DBG文件高于輸出名稱,輸入的名稱是一種偽符號.  
            調試時,DEBUG窗口輸出:裝載DLL的符號,則說明符號已被裝入;否則說明沒有裝載DLL的符號

            沒有裝入符號時,使用的位置字符串是DLL輸出的名稱,可能用DUMPBIN程序查看這個名稱:DUMPBIN  /EXPORTS  DLLname.:LoadLibraryA中設置中斷:"{,,Kernel32.dll}LoadLibraryA". 

            如裝入了符號,則要根據輸出函數和調用協議來計算函數名.如上例,LoadLibraryA使用__stdcall調用協議,據該協議,函數名以下劃線為前綴,所跟有進棧的字節數為后綴的@.一般說來,參數個數*4,就是參數占用棧空間的總字節數,LoadLibary的名稱便是:_LoadLibraryA@4,故最后的語法是:"{,,Kernel32.dll}_LoadLibraryA@4"  
             
            :常用的調用協議 

                 1__stdcall調用約定相當于16位動態庫中經常使用的PASCAL調用約定。在32位的VC++5.0PASCAL調用約定不再被支持(實際上它已被定義為__stdcall。除了__pascal外,__fortran__syscall也不被支持),取而代之的是__stdcall調用約定。兩者實質上是一致的,即函數的參數自右向左通過棧傳遞,被調用的函數在返回前清理傳送參數的內存棧,但不同的是函數名的修飾部分(關于函數名的修飾部分在后面將詳細說明)。 

                   _stdcallPascal程序的缺省調用方式,通常用于Win32  Api中,函數采用從右到左的壓棧方式,自己在退出時清空堆棧。VC將函數編譯后會在函數名前面加上下劃線前綴,在函數名后加上"@"和參數的字節數。 

                   2C調用約定(即用__cdecl關鍵字說明)按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對于傳送參數的內存棧是由調用者來維護的(正因為如此,實現可變參數的函數只能使用該調用約定)。另外,在函數名修飾約定方面也有所不同。 

                   _cdeclCC++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。VC將函數編譯后會在函數名前面加上下劃線前綴。是MFC缺省調用約定。 

            3__fastcall調用約定是如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數的(實際上,它用ECXEDX傳送前兩個雙字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧),在函數名修飾約定方面,它和前兩者均不同。 

                   _fastcall方式的函數采用寄存器傳遞參數,VC將函數編譯后會在函數名前面加上"@"前綴,在函數名后加上"@"和參數的字節數。         

                   4thiscall僅僅應用于“C++”成員函數。this指針存放于CX寄存器,參數從右到左壓。thiscall不是關鍵詞,因此不能被程序員指定。 

                   5naked  call采用1-4的調用約定時,如果必要的話,進入函數時編譯器會產生代碼來保存ESIEDIEBXEBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。naked  call不產生這樣的代碼。naked  call不是類型修飾符,故必須和_declspec共同使用。 

                   關鍵字  __stdcall__cdecl__fastcall可以直接加在要輸出的函數前,也可以在編譯環境的Setting...C/C++  Code  Generation項選擇。當加在輸出函數前的關鍵字與編譯環境中的選擇不同時,直接加在輸出函數前的關鍵字有效。它們對應的命令行參數分別為/Gz/Gd/Gr。缺省狀態為/Gd,即__cdecl 

                   要完全模仿PASCAL調用約定首先必須使用__stdcall調用約定,至于函數名修飾約定,可以通過其它方法模仿。還有一個值得一提的是WINAPI宏,Windows.h支持該宏,它可以將出函數翻譯成適當的調用約定,在WIN32中,它被定義為__stdcall。使用WINAPI宏可以創建自己的APIs  
             
            .位置斷點修飾符  
             
            1.
            跳躍計數

            功能是執行斷點但不在斷點處停止,直到執行完了一個特定的次數為止

            使用中首先設置一個標準的位置斷點,打開BreadPoint對話框,選中該斷點,單擊Condition,然后在彈出的對話框最下面的編輯控件中輸入次數

            只有當程序全速運行時,未執行的循環次數才有用.單步執行跨過斷點時不會更新跳躍計數

            :已知循環可能崩潰,但不清楚在哪次循環時,輸入遠遠大于總循環次數的跳躍計數修飾符,則在崩潰時可打開Breakpoint,其中將列出還未執行的循環次數,與總次數相減就可得已執行的次數.  
             
            2.
            條件表達式

            只有表達式為真時觸發.BreakpointCondition按鈕,選第一個編輯框,輸入表達式即可.規則

            .只可使用C類型比較運算符.  
            .
            表達式中不能調用任何函數.  
            .
            表達式中不能包含任何宏值

            表達式為@TIB=Thread  Infomation  Block  Linear  Address,則程序只在該特定線程中才會中斷.:線程@TIB地址值為0E000,則輸入"@TIB==0xE000",則在切換到該線程時中斷.W98,可用@FS=thread  specific  value. 

            如在某特定錯誤后中斷,則可用@ERR,"@ERR=2"表示在最后錯誤為ERROR_FILE_NOT_FOUND.@CLK,所有可在WATCH窗口中使用的偽寄存器均可用于條件表達式.  
             
            條件表達式可與跳躍斷點組合使用.  
             
            3.
            變量更改 

            在變量更改時中斷程序.只有當位置斷點執行時才能檢查變量.常用用調用棧高層的函數中發現出錯,需要深入調用棧,壓縮范圍找出根源時

            添加時在Breakpoint框第一個編輯框中輸入變量名(可以是指針指向聽對象:*p),在第二個編輯框中輸入要查看的項目數量.  
             
            .全局表達式和條件斷點.  
             
            調試器可監控某一地址和該地址上的1,24字節的內容.如可用硬件調試寄存器,則不影響速度;否則程序將單步執行ASM指令并在每一步中檢查條件,這將嚴重影響程序運行速度

            總共有4個調試寄存器.硬件調試寄存器不能處理超過1個雙字長的引用.確保利用硬件調試寄存器的最好方法是使用表達式和數據更改位置的實際地址值.例如:g_szGlobal是全局數組指針,地址為0x5000,則在Breakpoint對話框中DATA選項卡中將表達式斷點設為"*(char*))0x5000=='G'",但如果寫為"WO(0x5000)=='G',則用不到硬件調試寄存器,會單步執行每條指令

            與全局表達式斷點類似,使用變量的16進制地址給定長指針計算地址,并將要查看的單元數設為1,則全局變量斷點可發揮最付佳功效.如上例要在變量改動時中斷,則輸入:"*(long*)0x5000".  
             
            .WINDOWS消息斷點.  
             
            Breakpoint
            框的Message.需要指定一個窗口過程,注意:MFC世界中AfxWndProc是多數窗口的一個窗口過程,所以總會在該斷

            亚洲午夜久久久久久噜噜噜| 伊人色综合久久天天| 2020最新久久久视精品爱| 久久91精品久久91综合| 久久精品国产一区二区电影| 久久综合偷偷噜噜噜色| 久久亚洲国产成人影院| 韩国免费A级毛片久久| 久久精品一区二区影院 | 无码国产69精品久久久久网站| 一本色综合网久久| 国产亚州精品女人久久久久久| 久久婷婷五月综合成人D啪| 久久精品人人做人人爽97| 国产三级观看久久| 狠狠色丁香婷婷综合久久来| 久久99国产精品尤物| 国产精品久久久久免费a∨| 武侠古典久久婷婷狼人伊人| 久久强奷乱码老熟女| 亚洲午夜久久久精品影院| 国产精品免费看久久久| 国产精品久久久久久福利69堂| 无码精品久久久天天影视| 国产精品久久久99| 蜜臀久久99精品久久久久久小说| 久久97精品久久久久久久不卡| 久久强奷乱码老熟女| 要久久爱在线免费观看| 无码精品久久一区二区三区| 久久丝袜精品中文字幕| 国产A三级久久精品| 国产精品久久久久影院色| 国产成人精品久久一区二区三区av| 亚洲AV伊人久久青青草原| 狠狠色丁香久久综合婷婷| 99久久99这里只有免费的精品| 亚洲精品乱码久久久久久按摩| 99久久国产综合精品五月天喷水| 久久精品人人槡人妻人人玩AV| 亚洲精品无码成人片久久|