0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

回顧了快200個(gè)bug,這個(gè)老工程師總結(jié)這些教訓(xùn)

m3eY_edn_china ? 來源:未知 ? 作者:李倩 ? 2018-03-09 13:57 ? 次閱讀

我一直在如何跟蹤遇到的最有意思的bug。最近回顧了全部194個(gè)bug(時(shí)間跨度達(dá)13年),看看從中學(xué)到了什么經(jīng)驗(yàn)教訓(xùn)。下面是最重要的幾個(gè)經(jīng)驗(yàn)教訓(xùn),分為編碼、測(cè)試和調(diào)試這三大類:

編碼

這些是在過去給我?guī)砑謆ug的所有問題:

1. 事件順序:處理事件時(shí),很有必要提出下列問題:事件是否可以以一種不同的順序到達(dá)?如果我們從來沒有收到該事件,會(huì)怎樣?如果該事件連續(xù)出現(xiàn)兩次,又會(huì)怎樣?即使通常情況下這永遠(yuǎn)不會(huì)出現(xiàn),但系統(tǒng)(或交互系統(tǒng))的其他部分中的bug可能會(huì)導(dǎo)致這出現(xiàn)。

2. 處理太早:這是上述“事件順序”的一種特殊情況,不過它已引起了一些棘手的bug,所以它自成一類。比如說,如果信令消息接收太早,在配置和啟動(dòng)過程完成之前接收,許多奇怪的行為就會(huì)出現(xiàn)。另一個(gè)例子:當(dāng)某個(gè)網(wǎng)絡(luò)連接還沒有被列入空閑列表就被標(biāo)為斷開。調(diào)試這個(gè)問題時(shí),我們總是假設(shè)它在處于空閑列表時(shí)被設(shè)為斷開(但為什么它又沒有從列表上撤下?)。沒考慮到有時(shí)動(dòng)作發(fā)生太早要怪我們沒想到。

3. 隱蔽故障:一些跟蹤起來最棘手的bug(一方面)是由出現(xiàn)隱蔽故障、繼續(xù)執(zhí)行而不是給出錯(cuò)誤的代碼引起的。比如說,系統(tǒng)調(diào)用(比如綁定)返回未加檢查的錯(cuò)誤代碼。另一個(gè)例子:遇到錯(cuò)誤元素后,直接返回而不是給出錯(cuò)誤的解析代碼。調(diào)用在故障狀態(tài)下繼續(xù)持續(xù)一段時(shí)間,這大大加大了調(diào)試的難度。最好一旦檢測(cè)到故障情況,就返回錯(cuò)誤。

4. if語句:有幾個(gè)條件的if語句給我?guī)砹嗽S多bug。即使if語句概念上很簡(jiǎn)單,有多個(gè)條件需要跟蹤時(shí),它們也很容易搞錯(cuò)。如今我試著重寫代碼,力求更簡(jiǎn)單,避免要處理復(fù)雜的if語句。

5. Else:有幾個(gè)bug是沒有適當(dāng)考慮如果條件為假會(huì)發(fā)生什么而引起的。幾乎無一例外的是,每個(gè)if語句應(yīng)該有一個(gè)else部分。此外,如果你在if語句的一個(gè)分支中設(shè)置了某個(gè)變量,可能應(yīng)該在另一個(gè)分支也要設(shè)置該變量。與此相關(guān)的是標(biāo)志(flag)被設(shè)定的情況。僅僅添加設(shè)定標(biāo)志的條件很容易,但是容易忘了添加應(yīng)該重新設(shè)定標(biāo)志的條件。任由永久性設(shè)定的標(biāo)志留在那里可能會(huì)在將來導(dǎo)致bug。

6. 不斷變化的假設(shè):一開始最難預(yù)防的許多bug是由不斷變化的假設(shè)引起的。比如說,一開始,可能每天只有一個(gè)客戶事件。然后,按照這種假設(shè)編寫了許多代碼。后來某個(gè)時(shí)候,設(shè)計(jì)發(fā)生了變化,允許每天有多個(gè)客戶事件。出現(xiàn)這種情況后,就很難改變受到新設(shè)計(jì)影響的所有情況。很容易找到顯式依賴該變化的所有項(xiàng),但是難就難在,找到隱式依賴舊設(shè)計(jì)的所有情況。比如說,可能有代碼讀取某一天的所有客戶事件。隱式的假設(shè)可能是,結(jié)果集從不大于客戶數(shù)量。我沒有好的辦法可以預(yù)防這類問題,歡迎讀者建議。

7. 日志:深入了解程序執(zhí)行的任務(wù)至關(guān)重要,尤其是邏輯很復(fù)雜時(shí)。務(wù)必要添加足夠多(但是別太多)的日志,那樣你就能弄清楚為什么程序在執(zhí)行它執(zhí)行的任務(wù)。如果一切正常,日志并不重要,但是一旦出現(xiàn)了問題(這不可避免),你會(huì)很高興添加了適當(dāng)?shù)娜罩居涗??!?/p>

測(cè)試

作為一名開發(fā)者,除非進(jìn)行了測(cè)試,否則我不會(huì)說搞完了一項(xiàng)功能。至少,這意味著每一行新代碼或更改后的代碼至少執(zhí)行了一次。此外,單元測(cè)試或功能測(cè)試也很好,但還不夠。新功能還必須在類似生產(chǎn)環(huán)境的環(huán)境下加以測(cè)試和探究。下面是bug在測(cè)試方面給予我的一些重要的經(jīng)驗(yàn)教訓(xùn):

8. 零和空:務(wù)必要以零和空(合適的情況下)來進(jìn)行測(cè)試。對(duì)于字符串而言,這意味著既指長(zhǎng)度為零的字符串,又指內(nèi)容為空的字符串。另一個(gè)例子:在發(fā)送任何數(shù)據(jù)(零字節(jié))之前,測(cè)試TCP連接的斷開。沒有使用這些組合來測(cè)試是bug悄然出現(xiàn)的頭號(hào)原因,我在測(cè)試時(shí)是原本可以發(fā)現(xiàn)這些bug的。

9. 添加和刪除:新功能常常需要能夠?yàn)橄到y(tǒng)添加新配置,比如說用于電話號(hào)碼翻譯的新配置文件。所以測(cè)試它切實(shí)可行、以便添加新的配置文件很自然不過。然而,我發(fā)現(xiàn)很容易忘了還要測(cè)試配置文件的刪除。

10. 錯(cuò)誤處理:處理錯(cuò)誤的代碼常常很難測(cè)試。最好由自動(dòng)測(cè)試來檢查錯(cuò)誤處理代碼,但有時(shí)這不可能。這種情況下,我有時(shí)采用的一招就是,臨時(shí)修改代碼,讓錯(cuò)誤處理代碼運(yùn)行。要做到這一點(diǎn),最容易的方法就是反轉(zhuǎn)if語句,比如說將if語句由error_count > 0反轉(zhuǎn)為error_count == 0。另一個(gè)例子是誤拼數(shù)據(jù)庫列名,讓所需的錯(cuò)誤處理代碼運(yùn)行。

11. 隨機(jī)性輸入:常??梢园l(fā)現(xiàn)bug的一種測(cè)試方法就是使用隨機(jī)性輸入。比如說,H.323協(xié)議的ASN.1解碼可處理二進(jìn)制數(shù)據(jù)。通過發(fā)送有待解碼的隨機(jī)性字節(jié),我們發(fā)現(xiàn)了解碼器中的幾個(gè)bug。另一個(gè)例子是使用測(cè)試調(diào)用生成腳本,其中調(diào)用持續(xù)時(shí)間、回復(fù)延遲、第一方掛斷等都是隨機(jī)生成的內(nèi)容。這些測(cè)試腳本暴露了無數(shù)bug,尤其是接踵而至的事件引起的干擾。

12. 檢查什么不該發(fā)生:測(cè)試常常包括檢查所需的動(dòng)作已發(fā)生。但它很容易忽視相反的情況――檢查不該發(fā)生的動(dòng)作確實(shí)沒有發(fā)生。

13. 自行編寫工具:我通常構(gòu)建自己的小工具,好讓測(cè)試更容易。比如說,我在處理面向VoIP的SIP協(xié)議時(shí),寫了一個(gè)小腳本,就返回我所需要的頭和值。有了這個(gè)工具,許多個(gè)別情況測(cè)試起來很容易。另一個(gè)例子是可以進(jìn)行API調(diào)用的命令行工具。通過從小處著手,然后根據(jù)需要逐步添加功能,我最后開發(fā)出了非常實(shí)用的工具。自行編寫工具的好處就是,我獲得了所需的那種功能。

不過根本不可能在測(cè)試中發(fā)現(xiàn)所有bug,有一回,我改變了由兩部分組成的處理關(guān)聯(lián)號(hào)碼的機(jī)制:路由地址前綴(始終一樣),以及從000到999的動(dòng)態(tài)分配號(hào)碼。問題是,查找關(guān)聯(lián)時(shí),動(dòng)態(tài)分配號(hào)碼的第一位數(shù)字在查詢地址表之前就被誤刪除了。所以,不是尋找637之類的號(hào)碼,你尋找的是37,而這個(gè)號(hào)碼不在表中。這意味著,它一直尋找到100,所以前100個(gè)調(diào)用正常,而之余的所有900個(gè)調(diào)用失效。所以除非我在重新啟動(dòng)之前測(cè)試了100多次,否則在測(cè)試時(shí)發(fā)現(xiàn)不了這個(gè)問題。

調(diào)試

14. 討論:在過去對(duì)我?guī)椭畲蟮恼{(diào)試方法就是與同事討論問題。我常常只要向同事描述問題,就足以認(rèn)識(shí)到問題是什么。此外,即使同事不是很熟悉相應(yīng)代碼,常常也能給出好主意,表明哪里可能有問題。我在處理最棘手的bug時(shí),與同事討論這一招來得尤其管用。

15. 密切關(guān)注:調(diào)試某個(gè)問題花很長(zhǎng)時(shí)間時(shí),常常是由于我做了錯(cuò)誤的假設(shè)。比如說,我以為問題出現(xiàn)在某個(gè)方法中,而實(shí)際上這個(gè)問題根本不會(huì)出現(xiàn)在這個(gè)方法中?;蛘邟伋龅漠惓2⒉皇俏壹僭O(shè)的那個(gè)異常?;蛘呶乙詾樵谶\(yùn)行軟件的最新版本,實(shí)際上運(yùn)行的是舊版本。因此,一定要核實(shí)這些細(xì)節(jié),而不是犯想當(dāng)然的毛病。很容易看見預(yù)期看見的問題,而不是實(shí)際擺在那里的問題。

16. 最近的變化:過去可以運(yùn)行的代碼現(xiàn)在無法運(yùn)行時(shí),這常常是最后一個(gè)變更的對(duì)象引起的。有一回,最近變化的對(duì)象只是日志,但是日志中的錯(cuò)誤引起了更大的問題。為了讓諸如此類的回歸更容易找到,有必要在不同的提交代碼中實(shí)行不同的變更,并且要清楚說明變更。

17. 相信用戶:有時(shí)候用戶報(bào)告問題時(shí),我的本能反應(yīng)是“這不可能。他們肯定是哪里弄錯(cuò)了?!钡俏乙褜W(xué)會(huì)了擯棄這樣的反應(yīng)。結(jié)果往往證明,用戶報(bào)告的正是實(shí)際發(fā)生的問題。所以如今,我對(duì)用戶報(bào)告的問題信以為真。當(dāng)然,我仍反復(fù)核查各方面已正確設(shè)定。但是我碰過好多情況下,之所以發(fā)生奇怪的問題,是由于不同尋常的配置或意料之外的使用,而我默認(rèn)的假設(shè)是,它們是正確的,程序是錯(cuò)誤的。

18. 測(cè)試修正版:bug的修正版準(zhǔn)備就緒后,它必須進(jìn)行測(cè)試。先在沒有修正版的情況下運(yùn)行代碼,觀察bug。然后打上修正版,重復(fù)測(cè)試用例?,F(xiàn)在,錯(cuò)誤行為應(yīng)該消失。遵照這些步驟可以確保它其實(shí)是個(gè)bug,確保修正版確實(shí)解決了問題。這很簡(jiǎn)單,又必不可少。

其他意見

這13年來我一直在跟蹤我遇到的最棘手的bug,這期間發(fā)生了很大的變化。我開發(fā)過一個(gè)小型嵌入式系統(tǒng)、一個(gè)大型電信系統(tǒng)以及一個(gè)基于Web的系統(tǒng)。我用C 、Ruby、JavaPython編寫過代碼。我用C 編碼時(shí)期的幾類bug已完全消失,比如堆棧溢出、內(nèi)存損壞、字符串問題以及某些形式的內(nèi)存泄漏。

我遇到的其他問題(比如循環(huán)錯(cuò)誤和個(gè)別情況)少了很多,那是由于我一直對(duì)更多的邏輯進(jìn)行單元測(cè)試。但是,這并不意味著沒有bug,還是有bug。這篇文章總結(jié)的經(jīng)驗(yàn)教訓(xùn)幫助我在編碼、測(cè)試和調(diào)試這三個(gè)階段盡量減小破壞。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    915

    瀏覽量

    54651
  • BUG
    BUG
    +關(guān)注

    關(guān)注

    0

    文章

    155

    瀏覽量

    15628

原文標(biāo)題:回顧了快200個(gè)bug,這個(gè)老工程師總結(jié)這些教訓(xùn)

文章出處:【微信號(hào):edn-china,微信公眾號(hào):EDN電子技術(shù)設(shè)計(jì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    工程師13年編碼、測(cè)試和調(diào)試經(jīng)驗(yàn)大匯總

    最近,我回顧我所有的194個(gè)條目(從13歲開始),看看有什么經(jīng)驗(yàn)教訓(xùn)是我可以學(xué)習(xí)的。下面是我總結(jié)的最重要的經(jīng)驗(yàn)
    發(fā)表于 07-17 22:41 ?1987次閱讀

    作為一個(gè)工程師,千萬不要相信.....

    本帖最后由 eehome 于 2013-1-5 09:50 編輯 作為一個(gè)工程師,千萬不要相信.....(轉(zhuǎn)電子設(shè)計(jì)論壇上的一位工程師的話)有天,一個(gè)
    發(fā)表于 12-08 09:38

    設(shè)計(jì)教訓(xùn)如何成就稱職的FPGA資深工程師?

    !大家一起來看看特權(quán)同學(xué)告訴你哪些不為人知的秘訣:設(shè)計(jì)教訓(xùn)如何成就稱職的FPGA資深工程師?作為ASIC領(lǐng)域中一種半定制電路,F(xiàn)PGA的發(fā)展不但解決定制電路不足,并且能夠克服可編程器件門電路數(shù)有限
    發(fā)表于 08-20 16:50

    今日話題:硬件工程師or軟件工程師哪個(gè)有錢途?

    個(gè)是外在一個(gè)是內(nèi)在,當(dāng)然我還是喜歡硬的。。。專家又說了:純軟件開發(fā)的職業(yè)壽命是很短,也就是30歲之前。之后一定要另謀出路,轉(zhuǎn)設(shè)計(jì)或者管理。但很多做硬件和結(jié)構(gòu)的工程師,真的是越
    發(fā)表于 03-22 10:27

    電子工程師最關(guān)心的10個(gè)問題

    大城市與小城市的電子工程師哪個(gè)更好北上廣深是四個(gè)電子行業(yè)最集中的城市,工作機(jī)會(huì)很多,不少跨國公司的研發(fā)中心或總部大部分在這四個(gè)城市。大城市房?jī)r(jià)貴,交通費(fèi)用高,工作節(jié)奏,壓力大,但選
    發(fā)表于 05-18 11:49

    轉(zhuǎn): 13年棘手Bug調(diào)試總結(jié)18條教訓(xùn)

    有什么經(jīng)驗(yàn)教訓(xùn)是我可以學(xué)習(xí)的。下面是我總結(jié)的最重要的經(jīng)驗(yàn)教訓(xùn),包括編碼,測(cè)試和調(diào)試三個(gè)方面。編碼下面這些都是我經(jīng)歷過的會(huì)導(dǎo)致難點(diǎn)
    發(fā)表于 07-11 18:07

    中肯的總結(jié)!月薪4萬的IC驗(yàn)證工程師竟然每天做這些

    ,現(xiàn)在的趨勢(shì)都是在往UVM的驗(yàn)證環(huán)境上轉(zhuǎn)?!?測(cè)試用例(test plan)test plan的出爐是一個(gè)高質(zhì)量的工作,因?yàn)樗鼪Q定你驗(yàn)證的工作量,最重要是它決定你驗(yàn)證的完整度。驗(yàn)證工程師
    發(fā)表于 05-17 12:50

    電子工程師常見的錯(cuò)誤

    和復(fù)雜的電路圖,工程師們不時(shí)出現(xiàn)的小錯(cuò)誤是難免的,而且說不定就從哪次錯(cuò)誤中發(fā)現(xiàn)“新大陸”,那你就成為科技革命的先驅(qū)! 但是對(duì)于資歷尚淺的新手工程師來說,
    發(fā)表于 01-22 07:16

    個(gè)電子工程師的建議

    個(gè)電子工程師的建議 我當(dāng)電子工程師也是十余年,不算有出息,環(huán)顧四周,也沒有看見幾個(gè)有出息的!回顧
    發(fā)表于 11-21 10:57 ?1175次閱讀

    測(cè)試工程師心得總結(jié)

    測(cè)試工程師總結(jié),也許得大家有幫助,獻(xiàn)丑,
    發(fā)表于 03-04 16:46 ?0次下載

    工程師跨度13年、回顧194個(gè)bug總結(jié)的18條編碼、測(cè)試和調(diào)試經(jīng)驗(yàn)教訓(xùn)

    工程師跨度13年、回顧194個(gè)bug總結(jié)的18條編碼、測(cè)試和調(diào)試經(jīng)驗(yàn)教訓(xùn)。
    發(fā)表于 02-27 16:50 ?1007次閱讀

    硬件工程師路在何方 是“青春飯”還是“越越吃香”?

    硬件工程師已經(jīng)不再是越越吃香?也變成吃青春飯?“為什么會(huì)有越越吃香一說?”
    發(fā)表于 04-08 08:20 ?3.6w次閱讀

    這些技能是做工程師必備的

    不壞掉?我們有什么需要學(xué)習(xí)的軟技能。 以下是進(jìn)行電子工程師所需軟技能總結(jié): 自學(xué)能力 這個(gè)真的很重要,行業(yè)在飛速發(fā)展,不可能一直靠著學(xué)校教的東西來吃老本的。不要以為給本書,是個(gè)
    發(fā)表于 10-19 09:23 ?556次閱讀

    什么是FPGA工程師的核心競(jìng)爭(zhēng)力

    、debug、硬件實(shí)現(xiàn)的能力?或者,為什么說這些是專屬于FPGA工程師的核心競(jìng)爭(zhēng)力? 石認(rèn)為,這個(gè)問題其實(shí)可以引申為以下兩點(diǎn): 什么是只
    發(fā)表于 02-23 11:28 ?1484次閱讀

    電子工程師,站??!這些地雷別再踩!

    和復(fù)雜的電路圖,工程師們不時(shí)出現(xiàn)的小錯(cuò)誤是難免的,而且說不定就從哪次錯(cuò)誤中發(fā)現(xiàn)“新大陸”,那你就成為科技革命的先驅(qū)! 但是對(duì)于資歷尚淺的新手工程師來說,
    發(fā)表于 01-26 09:14 ?12次下載
    電子<b class='flag-5'>工程師</b>,站??!<b class='flag-5'>這些</b>地雷別再踩<b class='flag-5'>了</b>!