• <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 - 14,  comments - 57,  trackbacks - 0

            問題  

               上周開始,我們一個已經在線運行了快2年的游戲突然頻繁宕機,宕機前剛好上了一個資料片,提交了大批量的代碼。
            比較麻煩的是宕機的core文件里沒有任何有效CallStack信息。在隨后的多次宕機core文件里也都找不到有效的CallStack信息,定位問題變得無從入手。

            原因
             

               根據經驗,這是一個典型的棧破壞問題。一旦棧破壞了函數返回值后,堆棧完全是錯亂的,得不到任何有效信息。
            最開始我建議項目組的同事查看最近提交的代碼,看看能否找到線索。不過由于近一個月提交的代碼實在太多,大海撈針了一段時間后,
            毫無頭緒。
               棧覆蓋一般是因為memcpy或者是循環賦值語句導致的,一般棧覆蓋的層次不會太多,所以從底部往上找,應該能找到些有效的線索。
            不過,由于服務器函數經常會有Package的臨時變量,導致函數棧很大,從下往上找線索也很困難,很多似是而非的合法地址很容易分散精力。

            解決

              按照上面的分析,從底部往上找是大海撈針,那么從頂部往下找如何呢?
            這里先說明下一般函數堆棧幀的建立(未優化情況下的用戶函數):
            push rbp
            mov rbp, rsp
            從這里可以看出,本層函數的返回值是存儲在 [rbp + 8],而上層函數的rbp地址則存儲在 [rbp]。
            所以,從下網上找的時候,可以根據rbp逐步找到上層函數和上層函數的堆棧幀。

            那么如何往下找呢,假如知道了一個上層函數的rbp,如何獲取下層函數呢,
            這里有個小竅門,gdb7.X的版本有一個find功能,可以在內存區域搜索數值,
            從上往下找的時候,可以在堆棧查找本層 rbp的存放地址,從而確定下層函數rbp的存放地址。
            舉個例子:

            #0  0x00007ffff77d7830 in nanosleep () from /lib/x86_64-linux-gnu/libc.so.6
            #1  0x00007ffff77d76ec in sleep () from /lib/x86_64-linux-gnu/libc.so.6
            #2  0x000000000040070a in test1 () at main.cpp:9
            #3  0x0000000000400715 in test () at main.cpp:14
            #4  0x000000000040072b in main (argc=1, argv=0x7fffffffe648) at main.cpp:19

            這是一個典型的CallStack,讓我們先找到0x000000000040072b的堆棧信息吧。
            先 info r 查看當前的寄存器信息:
            得到 rsp為0x7fffffffe358

            find $rsp, +0x300, 0x000000000040072b
            0x7fffffffe548
            1 pattern found.

            只有一個地址,那么存放rbp的地址就是
            0x7fffffffe540了,
            繼續 find $rsp, +0x300, 0x7fffffffe540
            0x7fffffffe530
            1 pattern found.
            驗證下是否正確:
            x/10xg 
            0x7fffffffe530

            0x7fffffffe530: 0x00007fffffffe540      0x0000000000400715
            0x7fffffffe540: 0x00007fffffffe560      0x000000000040072b
            0x7fffffffe550: 0x00007fffffffe648      0x0000000100000000

            看到了吧,就是這樣找到了下一級的函數。
            真實環境中往往沒這么簡單,有時候會找到好幾個地址,這個時候需要自己逐個去偽存真了。

             

            posted on 2013-12-02 20:51 feixuwu 閱讀(792) 評論(0)  編輯 收藏 引用
            <2013年12月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            文章轉載請注明出處

            常用鏈接

            留言簿(11)

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            精产国品久久一二三产区区别| 亚洲αv久久久噜噜噜噜噜| 久久国产精品-国产精品| 国产99久久久久久免费看| 久久精品极品盛宴观看| 亚洲国产精品无码久久久蜜芽 | 久久久久久精品无码人妻| 久久99国产综合精品| 蜜桃麻豆www久久国产精品| 久久永久免费人妻精品下载| 久久伊人亚洲AV无码网站| 狼狼综合久久久久综合网| 亚洲人成网站999久久久综合| 国产欧美久久久精品| 久久丫精品国产亚洲av| 久久人人超碰精品CAOPOREN| 精品久久久久久久| 韩国免费A级毛片久久| 伊人久久大香线蕉综合热线| 久久免费精品视频| 国产精品久久久久jk制服| 亚洲AV无码久久精品色欲| 亚洲欧美久久久久9999| 精品久久久无码中文字幕天天| 久久99国产精品一区二区| 国产麻豆精品久久一二三| 亚洲va中文字幕无码久久| 波多野结衣AV无码久久一区| 香蕉久久久久久狠狠色| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久棈精品久久久久久噜噜| 99精品国产99久久久久久97| 免费无码国产欧美久久18| 热久久国产欧美一区二区精品 | 久久亚洲sm情趣捆绑调教| 亚洲国产成人久久笫一页| 亚洲v国产v天堂a无码久久| 国产精品美女久久福利网站| 久久综合久久综合亚洲| 中文字幕无码免费久久| 国产精品一区二区久久国产|