• <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ò)誤可能會很隱蔽,例如內(nèi)存寫超的代碼發(fā)生在某些庫代碼里,這種情況就要求 寫代碼時(shí)對自己所調(diào)用的庫函數(shù) 要大致了解 實(shí)現(xiàn)方法。總之,數(shù)組或者數(shù)組類指針是我們重點(diǎn)排查對象。
               未完待續(xù)……  peakflys

            posted on 2012-09-21 13:32 peakflys 閱讀(3959) 評論(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ù)  更多評論   

            <2012年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            導(dǎo)航

            統(tǒng)計(jì)

            公告

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

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久99精品久久久久久噜噜| 国产精品无码久久综合| 久久精品嫩草影院| 无码人妻少妇久久中文字幕蜜桃| 日韩久久久久中文字幕人妻| 久久精品人妻一区二区三区| 国产一区二区三精品久久久无广告| 99久久er这里只有精品18| 久久精品无码专区免费青青| 国产美女亚洲精品久久久综合 | 思思久久99热只有频精品66| 久久久青草青青国产亚洲免观| yellow中文字幕久久网| 久久中文娱乐网| 久久国产精品国产自线拍免费| 国产欧美久久久精品| 99久久久久| 午夜精品久久久内射近拍高清 | 国产精品永久久久久久久久久| 韩国三级中文字幕hd久久精品 | 婷婷久久久亚洲欧洲日产国码AV | 久久国产精品99精品国产| 97久久超碰国产精品2021| 麻豆精品久久精品色综合| 久久精品国产亚洲5555| 人妻无码精品久久亚瑟影视| 久久精品国产99久久无毒不卡| 久久精品一区二区| 欧美亚洲国产精品久久| 久久99国内精品自在现线| 精品99久久aaa一级毛片| 久久精品国产男包| 久久青草国产手机看片福利盒子| 91精品国产色综久久| 国产精品一区二区久久精品涩爱| 色综合久久久久无码专区| 久久99国产精品久久久| 99久久这里只精品国产免费| 国产精品久久影院| 亚洲国产美女精品久久久久∴ | 久久亚洲AV成人无码国产|