接獲報案,某台開發機器首次以.NET連接Oracle時出現問題(SqlPlus及PL/SQL Developer等工具運作正常),使用System.Data.OracleClient測試,在OracleConnection.Open()時彈出例外:

System.Exception: OCIEnvCreate 失敗並傳回代碼 -1 但錯誤訊息文字不可用。
   於 System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   於 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   於 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   於 System.Data.OracleClient.OracleConnection.Open()
   於 ConsoleApplication1.Program.Main(String[] args) 於 ConsoleApplication1\ConsoleApplication1\Program.cs: 行 15
   於 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   於 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   於 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   於 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   於 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   於 System.Threading.ThreadHelper.ThreadStart()

爬文發現此類錯誤常肇因於Oracle安裝不正確或Oracle Client目錄權限有誤,但苦主已重裝過Oracle Client,也確認NTFS權限已開啟,問題依舊...

線索中飄出妖氣,看來遇上了BOSS等級的茶包,趕緊拿出+256力量、攻擊速度提高50%、爆擊傷害提高20%的稀有裝備—Process Monitor!!

開啟Process Monitor後執行測試程式故意引發OCIEnvCreate錯誤,由檔案存取記錄觀察到可疑之處。程式居然在Windows\System32\下找到oci.dll,印象中它應該出現在Oracle Client安裝目錄下,對照其他運作正常機器後印證oci.dll的確出現在不該出現的地方。

推測System.Data.OracleClient在運作過程中假設oci.dll檔案所在的目錄就是Oracle Client的安裝位置,藉以推算其他相關檔案路徑。當oci.dll被錯置在System32,OracleClient做出錯誤判斷,導致後續的異常。

試著將System32\oci.dll更名為oci_.dll,出乎意料地,問題立刻消失!! 印證了它是造成離奇錯誤的原因。事後想想,如果不是Process Monitor抓出System32\oci.dll出現在不合理的路徑,又剛好依過去經驗察覺有異。這顆深埋System32裡的詭雷,應會導致重灌Oracle Client 100次也無濟於事,要等到放棄重灌OS才會"不藥而瘉"! 這回能快速抓出茶包,多少憑點運氣,而過去不知有多少最後重裝Windows後才修好的問題,背後就是這類詭雷作祟?

茶包世界變幻萬千,工具、運氣、邏輯與經驗,一樣都不可缺!! (筆記)


Comments

Be the first to post a comment

Post a comment