288 lines
12 KiB
HTML
288 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html><head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
<link href="sqlite.css" rel="stylesheet">
|
|
<title>The Error And Warning Log</title>
|
|
<!-- path= -->
|
|
</head>
|
|
<body>
|
|
<div class=nosearch>
|
|
<a href="index.html">
|
|
<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
|
|
</a>
|
|
<div><!-- IE hack to prevent disappearing logo --></div>
|
|
<div class="tagline desktoponly">
|
|
Small. Fast. Reliable.<br>Choose any three.
|
|
</div>
|
|
<div class="menu mainmenu">
|
|
<ul>
|
|
<li><a href="index.html">Home</a>
|
|
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
|
|
<li class='wideonly'><a href='about.html'>About</a>
|
|
<li class='desktoponly'><a href="docs.html">Documentation</a>
|
|
<li class='desktoponly'><a href="download.html">Download</a>
|
|
<li class='wideonly'><a href='copyright.html'>License</a>
|
|
<li class='desktoponly'><a href="support.html">Support</a>
|
|
<li class='desktoponly'><a href="prosupport.html">Purchase</a>
|
|
<li class='search' id='search_menubutton'>
|
|
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
|
|
</ul>
|
|
</div>
|
|
<div class="menu submenu" id="submenu">
|
|
<ul>
|
|
<li><a href='about.html'>About</a>
|
|
<li><a href='docs.html'>Documentation</a>
|
|
<li><a href='download.html'>Download</a>
|
|
<li><a href='support.html'>Support</a>
|
|
<li><a href='prosupport.html'>Purchase</a>
|
|
</ul>
|
|
</div>
|
|
<div class="searchmenu" id="searchmenu">
|
|
<form method="GET" action="search">
|
|
<select name="s" id="searchtype">
|
|
<option value="d">Search Documentation</option>
|
|
<option value="c">Search Changelog</option>
|
|
</select>
|
|
<input type="text" name="q" id="searchbox" value="">
|
|
<input type="submit" value="Go">
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function toggle_div(nm) {
|
|
var w = document.getElementById(nm);
|
|
if( w.style.display=="block" ){
|
|
w.style.display = "none";
|
|
}else{
|
|
w.style.display = "block";
|
|
}
|
|
}
|
|
function toggle_search() {
|
|
var w = document.getElementById("searchmenu");
|
|
if( w.style.display=="block" ){
|
|
w.style.display = "none";
|
|
} else {
|
|
w.style.display = "block";
|
|
setTimeout(function(){
|
|
document.getElementById("searchbox").focus()
|
|
}, 30);
|
|
}
|
|
}
|
|
function div_off(nm){document.getElementById(nm).style.display="none";}
|
|
window.onbeforeunload = function(e){div_off("submenu");}
|
|
/* Disable the Search feature if we are not operating from CGI, since */
|
|
/* Search is accomplished using CGI and will not work without it. */
|
|
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
|
|
document.getElementById("search_menubutton").style.display = "none";
|
|
}
|
|
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
|
|
function hideorshow(btn,obj){
|
|
var x = document.getElementById(obj);
|
|
var b = document.getElementById(btn);
|
|
if( x.style.display!='none' ){
|
|
x.style.display = 'none';
|
|
b.innerHTML='show';
|
|
}else{
|
|
x.style.display = '';
|
|
b.innerHTML='hide';
|
|
}
|
|
return false;
|
|
}
|
|
</script>
|
|
</div>
|
|
<div class=fancy>
|
|
<div class=nosearch>
|
|
<div class="fancy_title">
|
|
The Error And Warning Log
|
|
</div>
|
|
<div class="fancy_toc">
|
|
<a onclick="toggle_toc()">
|
|
<span class="fancy_toc_mark" id="toc_mk">►</span>
|
|
Table Of Contents
|
|
</a>
|
|
<div id="toc_sub"><div class="fancy-toc1"><a href="#setting_up_the_error_logging_callback">1. Setting Up The Error Logging Callback</a></div>
|
|
<div class="fancy-toc1"><a href="#interface_details">2. Interface Details</a></div>
|
|
<div class="fancy-toc1"><a href="#variety_of_error_messages">3. Variety of Error Messages</a></div>
|
|
<div class="fancy-toc1"><a href="#summary">4. Summary</a></div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function toggle_toc(){
|
|
var sub = document.getElementById("toc_sub")
|
|
var mk = document.getElementById("toc_mk")
|
|
if( sub.style.display!="block" ){
|
|
sub.style.display = "block";
|
|
mk.innerHTML = "▼";
|
|
} else {
|
|
sub.style.display = "none";
|
|
mk.innerHTML = "►";
|
|
}
|
|
}
|
|
</script>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h2 style="margin-left:1.0em" notoc="1" id="overview"> Overview</h2>
|
|
|
|
<p>SQLite can be configured to invoke a callback function containing
|
|
an error code and a terse error message whenever anomalies occur.
|
|
This mechanism is very helpful in tracking obscure problems that
|
|
occur rarely and in the field. Application developers are encouraged
|
|
to take advantage of the error logging facility of SQLite in their
|
|
products, as it is very low CPU and memory cost but can be a
|
|
huge aid for debugging.</p>
|
|
|
|
<h1 id="setting_up_the_error_logging_callback"><span>1. </span>Setting Up The Error Logging Callback</h1>
|
|
|
|
<p>There can only be a single error logging callback per process.
|
|
The error logging callback is registered at start-time using C-code
|
|
similar to the following:
|
|
|
|
</p><blockquote><pre>
|
|
<a href="c3ref/config.html">sqlite3_config</a>(<a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglog">SQLITE_CONFIG_LOG</a>, errorLogCallback, pData);
|
|
</pre></blockquote>
|
|
|
|
<p>The error logger callback function might look something like this:</p>
|
|
|
|
<blockquote><pre>
|
|
void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
|
|
fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>The example above illustrates the signature of the error logger callback.
|
|
However, in an embedded application, one usually does not print
|
|
messages on stderr. Instead, one might store the messages in a
|
|
preallocated circular buffer where they can be accessed when diagnostic
|
|
information is needed during debugging. Or perhaps the messages can be
|
|
sent to <a href="http://en.wikipedia.org/wiki/Syslog">Syslog</a>. Somehow, the
|
|
messages need to be stored where they are accessible to developers,
|
|
not displayed to end users.</p>
|
|
|
|
<p>Do not misunderstand: There is nothing technically wrong with displaying
|
|
the error logger messages to end users. The messages do not contain
|
|
sensitive or private information that must be protected from unauthorized
|
|
viewing. Rather the messages are technical in nature and are not useful
|
|
or meaningful to the typical end user. The messages coming from the
|
|
error logger are intended for database geeks. Display them accordingly.</p>
|
|
|
|
<h1 id="interface_details"><span>2. </span>Interface Details</h1>
|
|
|
|
<p>The third argument to the <a href="c3ref/config.html">sqlite3_config</a>(<a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglog">SQLITE_CONFIG_LOG</a>,...)
|
|
interface (the "pData" argument in the example above) is a pointer to arbitrary
|
|
data. SQLite passes this pointer through to the first argument of the
|
|
error logger callback. The pointer can be used to pass application-specific
|
|
setup or state information, if desired. Or it can simply be a NULL
|
|
pointer which is ignored by the callback.</p>
|
|
|
|
<p>The second argument to the error logger callback is an integer
|
|
<a href="rescode.html#extrc">extended error code</a>. The third argument to the error logger is the
|
|
text of the error message. The error message text is stored in a fixed-length
|
|
stack buffer in the calling function and so will only be valid for the
|
|
duration of the error logger callback function. The error logger should
|
|
make a copy of this message into persistent storage if retention of the
|
|
message is needed.</p>
|
|
|
|
<p>The error logger callback should be treated like a signal handler.
|
|
The application should save off or otherwise process the error, then return
|
|
as soon as possible. No other SQLite APIs should be invoked, directly or
|
|
indirectly, from the error logger. SQLite is <u>not</u> reentrant through
|
|
the error logger callback. In particular, the error logger callback
|
|
is invoked when a memory allocation fails, so it is generally a bad idea
|
|
to try to allocate memory inside the error logger. Do not even think
|
|
about trying to store the error message in another SQLite database.</p>
|
|
|
|
<p>Applications can use the <a href="c3ref/log.html">sqlite3_log(E,F,..)</a> API to send new messages
|
|
to the log, if desired, but this is discouraged. The <a href="c3ref/log.html">sqlite3_log()</a>
|
|
interface is intended for use by extensions only, not by applications.</p>
|
|
|
|
<h1 id="variety_of_error_messages"><span>3. </span>Variety of Error Messages</h1>
|
|
|
|
<p>The error messages that might be sent to the error logger and their
|
|
exact format is subject to changes from one release to the next. So
|
|
applications should not depend on any particular error message text formats or
|
|
error codes. Things do not change capriciously, but they do sometimes
|
|
changes.</p>
|
|
|
|
<p>The following is a partial list of the kinds of messages that might
|
|
appear in the error logger callback.</p>
|
|
|
|
<ul>
|
|
<li><p>
|
|
Any time there is an error either compiling an SQL statement
|
|
(using <a href="c3ref/prepare.html">sqlite3_prepare_v2()</a> or its siblings) or running an SQL
|
|
statement (using <a href="c3ref/step.html">sqlite3_step()</a>) that error is logged.
|
|
</p>
|
|
|
|
</li><li><p>
|
|
When a schema change occurs that requires a prepared statement to be reparsed
|
|
and reprepared, that event is logged with the error code SQLITE_SCHEMA.
|
|
The reparse and reprepare is normally automatic (assuming that
|
|
<a href="c3ref/prepare.html">sqlite3_prepare_v2()</a> has been used to prepared the statements originally,
|
|
which is recommended) and so these logging events are normally the only
|
|
way to know that reprepares are taking place.</p>
|
|
|
|
</li><li><p>
|
|
SQLITE_NOTICE messages are logged whenever a database has to be recovered
|
|
because the previous writer crashed without completing its transaction.
|
|
The error code is SQLITE_NOTICE_RECOVER_ROLLBACK when recovering a
|
|
<a href="lockingv3.html#rollback">rollback journal</a> and SQLITE_NOTICE_RECOVER_WAL when recovering a
|
|
<a href="wal.html">write-ahead log</a>.
|
|
</p>
|
|
|
|
</li><li><p>
|
|
SQLITE_WARNING messages are logged when database files are renamed or
|
|
aliased in ways that can lead to database corruption.
|
|
(See <a href="howtocorrupt.html#unlink">1</a> and <a href="howtocorrupt.html#alias">2</a> for
|
|
additional information.)
|
|
</p>
|
|
|
|
</li><li><p>
|
|
Out of memory (OOM) error conditions generate error logging events
|
|
with the SQLITE_NOMEM error code and a message that says how many bytes
|
|
of memory were requested by the failed allocation.
|
|
</p>
|
|
|
|
</li><li><p>I/O errors in the OS-interface generate error logging events.
|
|
The message to these events gives the line number in the source code where
|
|
the error originated and the filename associated with the event when
|
|
there is a corresponding file. </p>
|
|
|
|
</li><li><p>When database corruption is detected, an SQLITE_CORRUPT error
|
|
logger callback is invoked. As with I/O errors, the error message text
|
|
contains the line number in the original source code where the error
|
|
was first detected.</p>
|
|
|
|
</li><li><p>
|
|
An error logger callback is invoked on SQLITE_MISUSE errors.
|
|
This is useful in detecting application design issues when return codes
|
|
are not consistently checked in the application code.
|
|
</p></li></ul>
|
|
|
|
<p>SQLite strives to keep error logger traffic low and only send messages
|
|
to the error logger when there really is something wrong. Applications
|
|
might further cull the error message traffic
|
|
by deliberately ignore certain classes of error
|
|
messages that they do not care about. For example, an application that
|
|
makes frequent database schema changes might want to ignore all
|
|
SQLITE_SCHEMA errors.</p>
|
|
|
|
<h1 id="summary"><span>4. </span>Summary</h1>
|
|
|
|
<p>The use of the error logger callback is highly recommended.
|
|
The debugging information that the error logger provides has proven
|
|
very useful in tracking down obscure problems that occurs with applications
|
|
after they get into the field. The error logger callback has also
|
|
proven useful in catching errors occasional errors that the application
|
|
misses because of inconsistent checking of API return codes.
|
|
Developers are encouraged to implement an error logger callback early
|
|
in the development cycle in order to spot unexpected behavior quickly,
|
|
and to leave the error logger callback turned on through deployment.
|
|
If the error logger never finds a problem, then no harm is done.
|
|
But failure to set up an appropriate error logger might compromise
|
|
diagnostic capabilities later on.</p>
|
|
|