• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            在這一系列之前的兩篇文章中,我介紹了如何在windbg中查看調用棧的相關信息(詳見小覽call stack(調用棧)(一)),以及調用約定(詳見小覽call stack(調用棧) (二)——調用約定)。今天的這篇博客在二者的基礎之上,介紹如何使用調式器腳本程序來觀察調用棧。對CallStack感興趣的朋友可以在此基礎上開發更加詳盡的腳本來觀察CallStack的信息;對調試感興趣的朋友則可以看一下DScript的用處。

            我們先來看一個例子,下面的程序并不是一個優美的程序片段,但是它能夠幫助我們說明問題。程序使用了一個簡單的遞歸,把1到參數d的和累加到sum之上。在main中,我們把d設為10,這樣,在斷點處,我們就能獲得一個深度為11的調用棧。


            #include < stdio.h >

            int SumToOne( int d, int sum)
            {
            ??? sum
            += d;
            ???
            if (d != ? 1 )
            ??????? sum
            = SumToOne(d - 1 , sum);
            ???
            else
            ??????? sum
            = sum; // 這條語句方便設置斷點
            ??? return sum;
            }

            void main()
            {
            ???
            int sum = SumToOne( 10 , 0 );
            ??? printf(
            " sum=%d " , sum);
            }

            然后,在當前文件夾下,編輯調試器腳本文件DumpStack.txt,內容如下

            . printf " Dump %d frames\n " , ? $ { $ arg1}
            r
            $ t1 = @ebp ;
            . for ? ( r $ t0 = 1 ; ? $ t0 <=$ { $ arg1} ; r $ t0 =$ t0 + 1 )
            {
            ???
            . printf " frame %d, d=%d sum=%d\n " , ? $ t0 , poi ($ t1 + 8 ), poi ($ t1 + c )
            ??? r
            $ t1 = poi ($ t1 )
            }

            在windbg中,運行程序,當程序停止在斷點處時,執行腳本

            $$>a< “dumpStack.txt”a

            如下圖所示

            windbg

            我們看到了10個frame以及它的參數信息。

            現在,對這個調試腳本稍加解釋,稍顯來看看腳本的語法:

            1. 調試腳本的調用方法,windbg的語法是$$>a< “腳本文件名”參數。其中$$>a<中的a示意運行腳本的時候傳入參數(argument)
            2. 調試腳本的參數:在調試腳本中,用${$argi}來引用第i個參數。由于windbg默認16進制數,所以我們在調用這個參數的時候,用了a($$>a< "dumpStack.txt" a)
            3. 腳本變量的賦值和引用:這里使用了windbg別名(alias)的語法,大家可以把別名類比成c中的宏。在賦值的時候,用r $別名= 的格式,引用的時候,使用$別名
            4. 取值操作:c中的*p操作在windbg中,要用poi(p),原因是因為windbg默認支持MSAM語法。
            5. 控制語句:.for語句的使用和任何一種語言的for語句思想一樣,不再多述
            6. 輸出語句:.printf和c中的printf也基本相似,這里也不多述

            了解了語法之后,來看看算法:

            1. 腳本通過poi($t1+8), poi($t1+c)來顯示每個frame中d和sum的值,這里$t1代表了每個frame中ebp的值,所以簡單的說,就是把每個frame中ebp+8,ebp+c的值輸出。在介紹調用約定的博客中,我講述了這個偏移量的由來,在這里重溫一下。由于函數SumToOne是stdcall,壓棧順序從右往左,如下表所示
              前一個ebp
              eip
              d
              sum
              ebp指向存儲前一個ebo的位置,所以d的位置在ebp+8,sum在ebp+c
            2. 前往下一個frame,只需要把棧上ebp位置的值取出,作為新的ebp就可以了。因為基本上每一個程序在進行棧操作之前都會備份老的ebp(push ebp),然后把當前的esp作為新的ebp(mov ebp, esp)

            總結一下,今天這篇博文作為這個系列的結束,通過一個調式器腳本,復習了之前講述的調用棧的相關概念。同時也展示了調試器腳本的相關語法。

            久久国产综合精品五月天| 四虎国产精品免费久久久| 日韩精品久久久久久久电影| 中文字幕无码久久人妻| 一本色道久久99一综合| 99久久精品费精品国产一区二区| 久久久久久久尹人综合网亚洲| 免费观看成人久久网免费观看| 亚洲v国产v天堂a无码久久| 99久久精品免费看国产一区二区三区| 无码人妻久久一区二区三区免费丨 | 国产精品一区二区久久国产| 办公室久久精品| 久久天天躁夜夜躁狠狠| 91久久九九无码成人网站| 久久亚洲精品国产精品婷婷| 亚洲国产成人久久综合一 | 色婷婷综合久久久久中文| 亚洲国产精品婷婷久久| 亚洲中文字幕久久精品无码APP| 品成人欧美大片久久国产欧美| 久久婷婷激情综合色综合俺也去| 久久国产视屏| 亚洲狠狠综合久久| 国产午夜免费高清久久影院 | 久久国产成人精品麻豆| 久久久久久综合网天天| 久久久99精品成人片中文字幕| 国产精品免费福利久久| 国产亚洲精久久久久久无码77777 国产亚洲精品久久久久秋霞 | 久久精品亚洲精品国产欧美| 久久久久久午夜成人影院| 亚洲欧美国产日韩综合久久| 久久99精品久久久久久9蜜桃| 精品久久久久久中文字幕| 日韩人妻无码一区二区三区久久 | 一本一道久久a久久精品综合 | 国产精品一区二区久久国产| 亚洲AV无码久久| 一本久久a久久精品vr综合| 亚洲级αV无码毛片久久精品|