SQLite 可設定為在發生異常時呼叫包含錯誤代碼和簡潔錯誤訊息的回呼函式。此機制對於追蹤罕見且在現場發生的不明問題非常有幫助。鼓勵應用程式開發人員在產品中利用 SQLite 的錯誤記錄功能,因為其 CPU 和記憶體成本非常低,但對於除錯來說卻能有很大的幫助。
每個程序只能有一個錯誤記錄回呼。錯誤記錄回呼會在啟動時使用類似下列的 C 程式碼註冊
sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, pData);
錯誤記錄器回呼函式可能如下所示
void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){ fprintf(stderr, "(%d) %s\n", iErrCode, zMsg); }
上述範例說明了錯誤記錄器回呼的簽章。然而,在嵌入式應用程式中,通常不會在 stderr 上列印訊息。相反地,可以將訊息儲存在預先配置的循環緩衝區中,以便在除錯期間需要診斷資訊時存取。或者可以將訊息傳送至 Syslog。無論如何,訊息都需要儲存在開發人員可以存取的位置,而不是顯示給最終使用者。
不要誤會:將錯誤記錄器訊息顯示給最終使用者在技術上沒有問題。這些訊息不包含必須防止未經授權檢視的敏感或私人資訊。反之,這些訊息本質上是技術性的,對一般最終使用者而言並無用處或意義。來自錯誤記錄器的訊息是針對資料庫怪咖而設計的。請適當地顯示這些訊息。
傳遞給 sqlite3_config(SQLITE_CONFIG_LOG,...) 介面的第三個引數(在上述範例中為「pData」引數)是一個指向任意資料的指標。SQLite 將此指標傳遞給錯誤記錄器回呼的第一個引數。如果需要,可以使用指標傳遞應用程式特定的設定或狀態資訊。或者,它可以只是一個回呼忽略的 NULL 指標。
傳遞給錯誤記錄器回呼的第二個引數是一個整數 延伸錯誤碼。傳遞給錯誤記錄器的第三個引數是錯誤訊息的文字。錯誤訊息文字儲存在呼叫函式中的固定長度堆疊緩衝區中,因此只會在錯誤記錄器回呼函式的執行期間有效。如果需要保留訊息,錯誤記錄器應該將此訊息複製到永久儲存體中。
錯誤記錄器回呼應視為訊號處理常式。應用程式應儲存或以其他方式處理錯誤,然後盡快傳回。不應從錯誤記錄器直接或間接呼叫其他 SQLite API。SQLite 不會透過錯誤記錄器回呼進行再入。特別是,當記憶體配置失敗時會呼叫錯誤記錄器回呼,因此一般而言,嘗試在錯誤記錄器中配置記憶體並非明智之舉。甚至不要考慮嘗試將錯誤訊息儲存在另一個 SQLite 資料庫中。
應用程式可以使用 sqlite3_log(E,F,..) API 來傳送新訊息至記錄器(如果需要),但並不建議這麼做。sqlite3_log() 介面僅供擴充套件使用,不供應用程式使用。
可能傳送至錯誤記錄器的錯誤訊息及其確切格式會隨著不同版本而有所變更。因此,應用程式不應依賴任何特定錯誤訊息文字格式或錯誤碼。事情並非變化無常,但確實會偶爾變更。
以下是可能出現在錯誤記錄器回呼中的訊息類型的部分清單。
任何時候編譯 SQL 陳述式(使用 sqlite3_prepare_v2() 或其同類項)或執行 SQL 陳述式(使用 sqlite3_step())時發生錯誤,該錯誤便會記錄下來。
當發生需要重新剖析和重新準備已準備陳述式的架構變更時,該事件會以錯誤碼 SQLITE_SCHEMA 記錄下來。重新剖析和重新準備通常是自動的(假設最初已使用 sqlite3_prepare_v2() 來準備陳述式,這是建議的做法),因此這些記錄事件通常是知道正在重新準備的唯一方式。
當資料庫必須復原,因為前一個寫入者在未完成交易的情況下崩潰時,會記錄 SQLITE_NOTICE 訊息。復原回滾日誌時的錯誤碼為 SQLITE_NOTICE_RECOVER_ROLLBACK,而復原預先寫入日誌時的錯誤碼為 SQLITE_NOTICE_RECOVER_WAL。
當資料庫檔案以可能導致資料庫損毀的方式重新命名或設定別名時,會記錄 SQLITE_WARNING 訊息。(請參閱 1 和 2 以取得更多資訊。)
記憶體不足 (OOM) 錯誤狀況會產生錯誤記錄事件,其錯誤碼為 SQLITE_NOMEM,訊息則說明失敗的配置要求多少位元組的記憶體。
作業系統介面中的 I/O 錯誤會產生錯誤記錄事件。這些事件的訊息會提供錯誤在原始程式碼中的行號,以及有對應檔案時與事件相關的檔案名稱。
偵測到資料庫損毀時,會呼叫 SQLITE_CORRUPT 錯誤記錄器回呼。與 I/O 錯誤一樣,錯誤訊息文字包含錯誤首次偵測到的原始程式碼中的行號。
在 SQLITE_MISUSE 錯誤上會呼叫錯誤記錄器回呼。這有助於偵測應用程式設計問題,例如應用程式程式碼中未一致地檢查回傳碼。
SQLite 致力於保持錯誤記錄器流量低,並且僅在真正有問題時才將訊息傳送給錯誤記錄器。應用程式可以進一步刪除錯誤訊息流量,方法是故意忽略他們不關心的特定錯誤訊息類別。例如,經常變更資料庫結構的應用程式可能想要忽略所有 SQLITE_SCHEMA 錯誤。
強烈建議使用錯誤記錄器回呼。錯誤記錄器提供的偵錯資訊已證明在追蹤應用程式進入現場後發生的不明問題時非常有用。錯誤記錄器回呼也已證明在捕捉應用程式因 API 回傳碼檢查不一致而遺漏的偶發錯誤時非常有用。鼓勵開發人員在開發週期早期實作錯誤記錄器回呼,以便快速找出意外行為,並在部署期間保持錯誤記錄器回呼開啟。如果錯誤記錄器從未發現問題,則不會造成任何損害。但是,未設定適當的錯誤記錄器可能會在稍後損害診斷功能。