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

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久亚洲国产午夜精品理论片| 久久综合丝袜日本网| 囯产极品美女高潮无套久久久| 久久久久亚洲AV无码专区首JN | 久久伊人五月丁香狠狠色| 一极黄色视频久久网站| 久久综合久久自在自线精品自| 人妻无码αv中文字幕久久琪琪布| 久久96国产精品久久久| 中文字幕精品无码久久久久久3D日动漫| 久久综合久久综合亚洲| 精品久久久久久亚洲| 久久久精品国产亚洲成人满18免费网站 | 久久久这里有精品中文字幕| 亚洲色婷婷综合久久| 久久中文字幕一区二区| 亚洲女久久久噜噜噜熟女| 久久久久97国产精华液好用吗| 麻豆成人久久精品二区三区免费| 久久久久九国产精品| 99国内精品久久久久久久| 少妇高潮惨叫久久久久久| 久久久久国产一区二区| 精品精品国产自在久久高清| 欧美午夜精品久久久久免费视| 久久亚洲精品无码播放| 国产精久久一区二区三区| 2020久久精品国产免费| 亚洲午夜久久久久久久久电影网 | 亚洲综合精品香蕉久久网97| 午夜精品久久久久久毛片| 亚洲精品99久久久久中文字幕 | 精品久久久无码人妻中文字幕豆芽| 久久久久se色偷偷亚洲精品av| 亚洲国产精品无码久久久久久曰 | 久久久久se色偷偷亚洲精品av| 久久久久黑人强伦姧人妻| 国产精品欧美久久久久无广告 | 欧美亚洲另类久久综合婷婷| 久久午夜综合久久| 久久久久亚洲国产|