拿到了新版的sim-panalyzer,但是BUG還是有的…
首先,參考 J.Whitham博士的網頁
把2.02版就存在的bug給修掉。
上述的BUG修完之後,還是會出現下面這個莫明奇妙的錯誤:
fatal: dio should be either odir or bidirBuffer type!
從字面上意思看來是說沒把 DIO 這個模組中 buffer type的參數設定好,
當然事情不會這麼簡單,不然全世界的工程師都回家種田了…
經過跟 GDB 一整個下午的搏鬥,發現:
出包的DIO這個資料結構所屬的 pspec->style 這個變數,
在程式剛開始時,是正確的的依照組態檔被設定成 bidir 列舉型態
但是程式開始執行沒多久(大約第三個指令)
就會被改成一個非常大的數字,大約就是 0xFFFFFFE8 這麼大…
程式一看已經超過列舉型態的上限,當然就吐了一行
dio should be either odir or bidirBuffer type!
的錯誤訊息,同時自動終止sim-panalyzer主程式。
但是原始碼中在讀入命令列參數去初始化pspec->style之後,
就沒有任何程式敘述會動到該變數了,
這不就是密室殺人案嗎?
現場沒兇器,但人死了,倒底是誰殺的?
進一步往回追,發現這個pspec->style會被不正常的篡改,
很有可能是附近的另一個引數 pmwindex 因為某種緣故爆走的關係,
因為pspec->style被篡改的同時,
有某個指標以pmwindex為索引對某個記憶體位址作了寫入動作。
我們都知道指標是一種很恐怖的東西,
因為他賦予你在記憶體空間裡面隨地大小便、四處塗鴨的能力…
而有證人指出,案發當時的pmwindex
曾經從70左右的正常值爆增到 0xFFFFFFEF 這種天文數字,
很明顯的已經讓指標把位址指到某個他不該寫入的地方了…
往回追 pmwindex的相關程式,
又發現另一個相關的變數 tstart也會有爆增的現像,
很好,兇手快出現了,仔細檢查tstart是怎麼被更改的,
終於,在 /libpanalyzer/io_panalyzer.c #273 附近,
發現了一個該打屁股的錯誤:
if((lat - plat - pspec->nctcycles) > 0)
tstart = now + lat - plat - pspec->nctcycles;
詐看之下很好很強大是吧? 沒什麼問題啊?
但是仔細的追查這些變數的資料型態,
發現lat, plat pspec->nctcycles這三個出現在IF敘述裡面的變數,
其型態都是 UNSIGNED !!
用減法比大小之前沒有作型態轉換! 這就是兇手!
都已經是無號數了,不管怎麼作減法,都不會減出負數的!
所以這個if敘述就是 if(1) 永遠執行的意思…
吐血之餘把程式改成:
if(( (int)lat - (int)plat - (int)pspec->nctcycles) > 0)
tstart = now + lat - plat - pspec->nctcycles;
無厘頭錯誤消失,程式正常跑完…
奇妙的是同一個原始檔的另一處有一個一模一樣的錯誤,
但是被某位叫 Ludo的好心人修掉了:
#201
/* Ludo: added some casts here, since all variables are unsigned!
This solves some segmentation faults. */
if(((int)lat - (int)plat - (int)pspec->nctcycles) > 0)
// if((lat - plat - pspec->nctcycles) > 0)
tstart = now + lat - plat - pspec->nctcycles;
送佛也送上西天嘛~
還是這也是某種保護智財權的手段... 囧rz
結論:
1.使用c語言請隨時注意資料型態是否相容。
2.指標這東西威力強大,特別是在您需要密室殺人的時候,實為好用技倆。
作者已經移除這則留言。
回覆刪除