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

            段錯(cuò)誤造成的常見詭異宕機(jī)情況總結(jié)(中)

               上面一種情況是自己內(nèi)存寫超了,寫到了用戶態(tài)別的結(jié)構(gòu)所在的內(nèi)存,特點(diǎn)就是core文件顯示 別處對象的內(nèi)容亂七八糟,且一般是在對象析構(gòu)時(shí)發(fā)生,這次講解一下,自己把自己寫壞的情況。
              1 /**
              2  *\author peakflys 
              3  *\brief 堆棧崩潰問題
              4  
            */
              5 #include <iostream>
              6 using namespace std;
              7 
              8 struct Temp
              9 {
             10     int a;
             11     unsigned char b[4];
             12 };
             13 
             14 class Test
             15 {
             16 public:
             17     void temp();
             18 private:
             19     void fill(unsigned char *data);
             20     Temp tt;
             21 };
             22 void Test::fill(unsigned char *data)
             23 {
             24     for(int i=0;i<20;++i)
             25     {
             26         data[i] = i;
             27         cout<<"data["<<i<<"]:\t"<<(void *)&data[i]<<endl;
             28     }
             29 }
             30 void Test::temp()
             31 {
             32     Temp t;
             33     fill((unsigned char *)&t);
             34 }
             35 
             36 int main()
             37 {
             38     Test *pt = new Test();
             39     pt->temp();
             40     delete pt;
             41     return 0;
             42 }
            運(yùn)行結(jié)果:
            data[0]:        0x7fffa4a38c60
            data[1]:        0x7fffa4a38c61
            data[2]:        0x7fffa4a38c62
            data[3]:        0x7fffa4a38c63
            data[4]:        0x7fffa4a38c64
            data[5]:        0x7fffa4a38c65
            data[6]:        0x7fffa4a38c66
            data[7]:        0x7fffa4a38c67
            data[8]:        0x7fffa4a38c68
            data[9]:        0x7fffa4a38c69
            data[10]:       0x7fffa4a38c6a
            data[11]:       0x7fffa4a38c6b
            data[12]:       0x7fffa4a38c6c
            data[13]:       0x7fffa4a38c6d
            data[14]:       0x7fffa4a38c6e
            data[15]:       0x7fffa4a38c6f
            data[16]:       0x7fffa4a38c70
            data[17]:       0x7fffa4a38c71
            data[18]:       0x7fffa4a38c72
            data[19]:       0x7fffa4a38c73
            段錯(cuò)誤 (core dumped)
            堆棧情況:
            Program terminated with signal 11, Segmentation fault.
            [New process 18836]
            #0  0x0000000000400a3e in main ()
            (gdb) bt
            #0  0x0000000000400a3e in main ()
            (gdb) 
            總結(jié):temp成員函數(shù)在調(diào)用fill成員函數(shù)時(shí)通過thiscall方式調(diào)用,gcc具體實(shí)現(xiàn)是把this指針像普通參數(shù)一樣入棧傳過去,而VS是在定參的情況下,this指針通過ECX傳入,這個(gè)就是這次悲劇的禍根,通過gdb打印出來的情況是:
            (gdb) info fr
            Stack level 0, frame at 0x7fff49980a50:
             rip = 0x400975 in Test::fill(unsigned char*) (test.cpp:22); saved rip 0x400a56
             called by frame at 0x7fff49980a80
             source language c++.
             Arglist at 0x7fff49980a40, args: this=0x601280, data=0x3d9da611a0 "\203?\001\031?f\203;"
             Locals at 0x7fff49980a40, Previous frame's sp is 0x7fff49980a50
             Saved registers:
              rbp at 0x7fff49980a40, rip at 0x7fff49980a48
            (gdb) p &this
            $7 = (Test * const *) 0x7fff49980a20
            (gdb) p &data
            $8 = (unsigned char **) 0x7fff49980a18
            通過對data的持續(xù)寫最終導(dǎo)致棧地址寫到了this指針?biāo)诘臈?nèi)存,這樣再從那塊地址取this指針時(shí),取的就不是this指針,最終從未知的“that指針”取數(shù)據(jù),十有八九程序就掛了。
               這種情況出現(xiàn)在linux服務(wù)器上(確切的說是使用GCC編譯器編譯的程序上),特點(diǎn)就是 發(fā)生在類函數(shù)里,宕機(jī)位置不一定,每一次宕機(jī) 查看 類體對象內(nèi)容也是錯(cuò)亂的,并且 關(guān)鍵是 this指針發(fā)生了改變,打印其地址時(shí)很可能是無法訪問,預(yù)防方法還是邊界訪問檢查。
                結(jié)合上一例子來看,段錯(cuò)誤宕機(jī)重點(diǎn)嫌疑對象就是數(shù)組!排查的時(shí)候首先在空間近鄰或者時(shí)間近鄰上查找。實(shí)際應(yīng)用中這類錯(cuò)誤可能會(huì)很隱蔽,例如內(nèi)存寫超的代碼發(fā)生在某些庫代碼里,這種情況就要求 寫代碼時(shí)對自己所調(diào)用的庫函數(shù) 要大致了解 實(shí)現(xiàn)方法。總之,數(shù)組或者數(shù)組類指針是我們重點(diǎn)排查對象。
               未完待續(xù)……  peakflys

            posted on 2012-09-21 13:32 peakflys 閱讀(3966) 評論(2)  編輯 收藏 引用 所屬分類: 服務(wù)器

            評論

            # re: 段錯(cuò)誤造成的常見詭異宕機(jī)情況總結(jié)(中) 2012-09-21 16:29 zuhd

            這種情況比較有意思  回復(fù)  更多評論   

            # re: 段錯(cuò)誤造成的常見詭異宕機(jī)情況總結(jié)(中) 2014-05-08 11:35 samjiao

            這個(gè)地址可能給你誤解了
            (gdb) p &data
            $8 = (unsigned char **) 0x7fff49980a18
            這是指向地址的地址,往data寫內(nèi)容是是寫到 0x7fff49980a18存放的地址上去,因此破壞的不是this指針。
            這種情況下如果有多重調(diào)用,破壞的是上級的堆棧結(jié)構(gòu)。因此導(dǎo)致segment fault。
            你說的額數(shù)組是最大嫌疑非常有啟發(fā)。  回復(fù)  更多評論   

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            導(dǎo)航

            統(tǒng)計(jì)

            公告

            人不淡定的時(shí)候,就愛表現(xiàn)出來,敲代碼如此,偶爾的靈感亦如此……

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久久久99精品免费观看| 久久亚洲2019中文字幕| 久久精品国产国产精品四凭| 久久久久亚洲精品无码网址| 亚洲国产精品一区二区三区久久 | 午夜不卡久久精品无码免费| 亚洲婷婷国产精品电影人久久 | 影音先锋女人AV鲁色资源网久久| 亚洲成av人片不卡无码久久 | 亚洲国产成人久久综合碰| 亚洲国产高清精品线久久 | 亚洲国产另类久久久精品黑人| 久久丫精品国产亚洲av| 国内精品伊人久久久久AV影院| 91久久精品视频| 久久久精品久久久久影院| 国产精品99久久久久久人| 国产—久久香蕉国产线看观看| 日韩AV无码久久一区二区| 大香网伊人久久综合网2020| 性欧美大战久久久久久久久| 国产成人久久精品区一区二区| 久久精品国产亚洲αv忘忧草| 久久se精品一区精品二区| 大香伊人久久精品一区二区| 777久久精品一区二区三区无码 | 日日噜噜夜夜狠狠久久丁香五月| 精品久久久久久99人妻| 无码精品久久久天天影视| 精品久久人人妻人人做精品| 久久久精品人妻一区二区三区四 | 国产精品久久网| 久久影院久久香蕉国产线看观看| 亚洲国产成人久久综合一| 无码超乳爆乳中文字幕久久| 久久这里只有精品首页| 欧美成人免费观看久久| 青青热久久国产久精品 | 亚洲精品无码专区久久同性男| 国产成人精品免费久久久久| 欧美一区二区三区久久综|