程序員量子力學-海森堡式BUG

今天在閱讀《The Pragmatic Programmer》的時候發現書中提到了Heisenbug讓我想起來了多年之前在開發中碰到的一個海森堡式的BUG。
The Pragmatic Programmer數據庫

海森堡是德國著名的物理學家,量子力學的創始人之一,「哥本哈根學派」的表明人物。單元測試

若是你們對這段歷史或者物理原理不清楚的話,推薦你們閱讀《上帝擲骰子嗎》,很是好看的一本關於量子力學歷史的科普書。測試

上帝擲骰子嗎

海森堡對量子力學的一個重要貢獻是提出了著名的「不肯定性原理」(又稱「海森堡測不許原理」),在一個量子力學系統中,一個運動粒子的位置和它的動量不可被同時肯定。這是由於要觀察就必須用光擊中被觀察的粒子,經過反射的光波來肯定粒子的位置。然而觀測所發出的光必然會影響被觀測的粒子。ui

海森堡式的BUG是該物理原理在軟件開發中的一個表現,固然這是一個類比,它和量子力學沒有半毛錢的關係。舉個例子吧,當程序出現了一個bug,程序猿爲了找到bug出現的緣由,在出現bug的代碼處加入了一條打印語句,想要了解在出現bug的時候本地變量和參數的值以便肯定bug出現的緣由。然而奇蹟出現了,當加入打印語句後,bug消失了。哦,買糕的,這條打印語句不就是射向粒子的那束光麼?debug

下面,我來給你們分享一下我遇到的那個Heisenbug。設計

當時咱們團隊作一個商用軟件從Windows平臺到Linux平臺的移植,由於該軟件早期是以Mac爲平臺編寫的(那是Mac尚未像如今這樣風靡),因此咱們的移植平沒有遇到太大的困難,主要的工做是包括:調試

  • 用QT來實現全部的UI組件日誌

  • 支持Linux下的數據庫鏈接code

  • 移植C++非標準的使用orm

  • Unicode的支持

項目的前期很是順利,然而就是當項目接近尾聲的時候,一個可怕的海森堡式bug出現了,產品的release版本會出現一些隨機的錯誤,這些錯誤都很奇怪,並無一個統一的表現。而這些錯誤在debug版本中徹底不會出現。爲了解決這個問題,在boss的率領下咱們開始加班除蟲。在當時公司加班仍是不多見的,一方面歐洲公司以人爲本,並不鼓勵加班;另外一方面咱們團隊,你們能力都很強,不須要加班來解決問題。然而這個bug屬於必需要解決的問題,加班在所不免。

但是要解決問題這個問題還真是不容易,由於問題不會出如今debug版本中,因此用gdb加斷點單步調試的方式根本沒有用。因此調試的方式就只剩下了打日誌。通過我一天不斷的加入日誌,運行測試,加入日誌,運行測試…… 最終終於找到了問題的緣由。通常狀況下,找到問題的緣由比解決問題要困難的多,當你發現問題的緣由後,解決的方法就像禿子頭上的蝨子。

原來,這個問題是因爲咱們生成軟件版本的方法所形成的。

爲了在build的時候自動的生成軟件的版本,咱們的天才工程師想了一個好主意,那就是把版本信息寫入Linux的可執行文件中(你們能夠參考ELF的規範)。咱們的軟件能夠從文件中讀出這個版本,讓後經過API告訴任何組件或者使用者當前的軟件版本是什麼。不得不認可這是一個很是有創意的好主意,可是這也是引發錯誤的主要緣由。因爲疏忽,在寫入版本信息的時候,並無嚴格按照規範來寫,因此其實版本信息超出了本應寫入的位置,也就是說寫越界了,破壞了程序數據,因此形成了release版本中的錯誤。但是爲何debug版本沒有問題呢?緣由大概是debug版本因爲加入了大量的代碼和調試信息,版本信息極可能只是覆蓋了調試信息而沒有影響程序的正常運行。

這麼多年過去了,不少細節我已經記不清楚啦,然而對於這個海森堡式的bug,如今想一想,咱們應該能夠作的更好:

  • 設計評審
    咱們鼓勵創新,當引入一個新的解決方案,尤爲是別人不多或根本沒有使用過得方案時,咱們必須很是當心。由於沒有人碰到一樣的問題。認真的設計評審或許能夠有所幫助。

  • 代碼審查
    若是當時咱們可以認真的進行代碼審查,也許咱們能發現這個問題。但也許即便進行代碼審查,也不必定能發現這個錯誤。團隊中沒有幾我的可以搞懂ELF的規範

  • 單元測試
    單元測試能幫助發現這個問題麼?也許能夠,當時咱們並無就這個功能引入任何的單元測試。

最後引用一個我發現的軟件開發中的測不許原理:軟件的需求和完成時間不可能同時測準,若是你清楚需求是什麼,那麼你就不知道何時能完成;若是你知道何時要作完,那你根本就不知道需求是什麼。

相關文章
相關標籤/搜索