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

            那誰的技術(shù)博客

            感興趣領(lǐng)域:高性能服務(wù)器編程,存儲,算法,Linux內(nèi)核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數(shù)據(jù)加載中……

            [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤

            今天遇到一個問題,調(diào)試了一天.

            大致描述一下,移植一個開源項目的代碼,原來在mips平臺上運行正常,后來到arm平臺的機器上運行,結(jié)果運行時出錯了.

            一般的,這樣的問題,腦子里面第一下的反應(yīng)就是由于字節(jié)序問題造成的.

            我起初也是這么想的.因為從出錯的現(xiàn)象來看,是某個字段不符合要求造成的出錯.于是沿著這個思路去找BUG.抓包來分析,看上去也是這樣的.但是,追蹤的過程中發(fā)現(xiàn),有多次收發(fā)報文的過程,這個字段,或者說擁有這個字段的結(jié)構(gòu)體在多處都有使用,改了一處,在別的地方其它字段又有報錯.

            回頭看代碼,發(fā)現(xiàn)在最開始解析包頭的時候,已經(jīng)造成了緊跟著包頭的某個字段出現(xiàn)異常,于是,想到是不是在不同的平臺上,sizeof(某結(jié)構(gòu)體)的數(shù)值不一樣造成,要驗證這一點,給包頭結(jié)構(gòu)體的定義加上嚴(yán)格按照一個字節(jié)對齊的限制,重新運行程序,可以了.

            最后再來稍微詳細(xì)一些看這個問題,假設(shè)包頭結(jié)構(gòu)體的定義是:
            typedef unsigned short u16;

            struct header
            {
                u16 a;
                u16 b;
                u16 c;
            };
            如果解析的時候,sizeof(struct header) != sizeof(u16) * 3,那么使用sizeof(struct header)解析接收到緩沖區(qū)的數(shù)據(jù)就會出現(xiàn)問題,因為它會對緊跟著的數(shù)據(jù)也造成影響.程序的異常正是源于此.在代碼的處理中,首先接收包頭,對包頭的數(shù)據(jù)進(jìn)行了字節(jié)序轉(zhuǎn)換,然后,又對緊挨著包頭的結(jié)構(gòu)體進(jìn)行了相同的字節(jié)序轉(zhuǎn)換,由于包頭結(jié)構(gòu)體的字節(jié)序轉(zhuǎn)換同時影響了緊挨著的結(jié)構(gòu)體中的數(shù)據(jù),所以這些數(shù)據(jù)實際上被進(jìn)行了兩次的字節(jié)序轉(zhuǎn)換,這才造成了這個問題"看上去"是字節(jié)序轉(zhuǎn)換不當(dāng)造成的"表面原因",如果跟著這個原因繼續(xù)跟蹤下去,以這個思路解決問題,治標(biāo)而不治本.

            總結(jié):
            1. 收發(fā)數(shù)據(jù)的結(jié)構(gòu)體定義需要嚴(yán)謹(jǐn)一些,如果不能確定如何對齊,最好自己定義一個對齊的標(biāo)準(zhǔn).
            2. 經(jīng)驗有的時候也不見得就是好事,有時候會讓自己陷入思維定式的怪圈,比如在這個問題的處理上,由于問題在切換了硬件平臺的時候才出現(xiàn),正好又是兩個字節(jié)序不一樣的硬件平臺,所以經(jīng)驗將我的思路導(dǎo)向了字節(jié)序不正確這個方向上.



            posted on 2009-10-15 20:32 那誰 閱讀(5251) 評論(6)  編輯 收藏 引用 所屬分類: 經(jīng)驗教訓(xùn)

            評論

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤  回復(fù)  更多評論   

            有假設(shè)就寫到代碼里嘛。
            隨便找個編譯單元:
            static char assume[sizeof(header)==sizeof(u16)*3?1:-1];

            或者就在header下方寫:
            typedef int assume[sizeof(header)==sizeof(u16)*3?1:-1]];

            2009-10-15 23:35 | OwnWaterloo

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤  回復(fù)  更多評論   

            按照一字節(jié)對齊,不要使用編譯器默認(rèn)的。
            2009-10-16 09:00 | guest

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤[未登錄]  回復(fù)  更多評論   

            這種時候最好加上一個#pragma pack命令,對應(yīng)于gcc好像是__attribute吧。
            2009-10-16 17:31 | 欲三更

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤  回復(fù)  更多評論   

            學(xué)習(xí)分享!
            2009-10-18 19:59 | 伊莎貝兒女裝

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤  回復(fù)  更多評論   

            建議不要與語言,CPU相關(guān)。否則,你下次,還依然還要被教訓(xùn)
            2009-10-18 21:35 | zdhsoft

            # re: [經(jīng)驗教訓(xùn)總結(jié)]協(xié)議包頭結(jié)構(gòu)體定義不嚴(yán)謹(jǐn)造成的錯誤  回復(fù)  更多評論   

            不太明白,你一個結(jié)構(gòu)中三個成員都是相同類型的,什么情況下會出現(xiàn)整個結(jié)構(gòu)的大小不等于成員類型大小的3倍?
            2009-11-18 19:44 | MaTox
            久久99九九国产免费看小说| 狠狠色丁香婷婷久久综合五月 | 亚洲欧美精品伊人久久| 亚洲色婷婷综合久久| 久久久久久久久久久久中文字幕 | 国产精品久久永久免费| 99久久亚洲综合精品网站| 亚洲综合久久综合激情久久| 久久久久99精品成人片| 亚洲伊人久久精品影院| 久久久免费精品re6| 精品久久久久久无码免费| 精品久久久久久国产潘金莲 | 国产精品久久久久影视不卡| 精品久久久久久无码中文字幕| 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 | 成人午夜精品久久久久久久小说 | 久久婷婷五月综合色高清| 久久精品国产亚洲Aⅴ香蕉| 人人狠狠综合久久亚洲| 国产综合久久久久久鬼色| 亚洲成色999久久网站| 国内精品人妻无码久久久影院导航 | 久久久高清免费视频| 久久综合九色欧美综合狠狠| 国产精品一区二区久久| 99久久精品国内| 波多野结衣久久一区二区| 91精品久久久久久无码| WWW婷婷AV久久久影片| 99久久精品免费看国产一区二区三区| 久久国产精品免费一区| 国产一区二区三区久久| 久久综合噜噜激激的五月天| 偷偷做久久久久网站| 亚洲国产精品综合久久一线| 久久久高清免费视频| 亚洲国产高清精品线久久 | 久久久久一级精品亚洲国产成人综合AV区| 国产成人精品久久一区二区三区| 午夜精品久久久久久久|