最近在給一個老項目做數據對接接口。
背景一
該項目最后更新日期為2006年,使用ASP.NET WebForm、.Net2.0、OJB、Castle Avtive Record等。由於是某集團的子系統之一,所以在獲取人員信息時,必須使用已經封裝好的組件。
背景二
接口對面是一個JAVA項目,一般這種老系統我都建議使用SOAP服務做對接,要是用Restful服務就得再新起一個接口項目專門做JAVA對接,然后再用老系統與接口項目對接,麻煩。結果同事去談需求的時候壓根沒注意老項目的年代,一上去就奔着Restful服務去了,聊完以后人家兩天就把代碼寫完了,我們這邊懵逼了。讓對方改代碼也不現實,畢竟一開始是我們考慮欠妥。最后決定,把老項目升級到.Net4.0,直接使用WebAPI。
正文
升級過程非常順利,編譯也沒有任何錯誤。運行一下,功能也都沒有任何問題,心里一陣竊喜。那就到正式環境部署一版.Net4.0的跑跑吧,畢竟正式環境還是Windows Server 2003+IIS6.0。部署完畢以后啟動后台登錄頁一看,傻眼了。
一開始以為是服務器配置的問題,結果把發布文件部署在本地也是同樣的異常。很明顯,這種異常只會出現在發布后的項目里。從調用棧里可以獲取到一些信息,但是還是太少。想要調試發布的代碼,可以使用VS自帶的遠程調試工具。
遠程調試步驟就不多說,網上有很多例子。調試過程中會遇到無法命中斷點的情況。
這種情況有可能是你要調試的項目沒有載入斷點符號,載入符號的具體步驟如下:
1.打開調試里的模塊窗口。
2.找到項目的dll,右鍵點擊加載符號,就能命中斷點了。
通過調試發布以后的項目,發現有一處參數傳值不正確。正常情況下,參數key的值應該是GetObjectByID,而這里竟然將構造函數傳進來了。顯然“未將對象引用設置到對象的實例”是由這個key造成的。
沿着調用棧繼續往上找,發現一段這樣的代碼,根據調用棧獲取調用函數的名稱。也就是說,問題可能出現在skipStack上了。
隨后,我將發布前和發布后的調用棧信息輸出出來對比(左邊是發布前,右邊是發布后)。
從輸出里可以看到,發布前比發布后多了一步函數調用(因為.Net2.0還不支持參數默認值,所以通過這種方式實現默認參數的效果)。
引起調用棧不一致的原因可能是在Release時,多出的一步調用被編譯器優化掉了(我將VS的運行模式換成Release以后異常也能重現)。至於以前為什么沒出現這樣的問題,可能是當時的編譯器優化能力沒現在這么強吧,06年那會兒應該是VS2005。
至此,本次抓臭蟲的任務圓滿完成。