Improvements to memory leak detection.  The --backtrace=NNN option is now
recognized by tester.tcl.  Memory leak summaries are automatically written
to the file ./memleak.txt and each leak is tagged with the test in which
it occurred.  The quick.test script runs on Linux with no errors and
no leaks. (CVS 4273)

FossilOrigin-Name: 21f6b31097692171c6493e6ca6de6acbd62dc595
diff --git a/src/btree.c b/src/btree.c
index f92e32c..bb740a7 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.409 2007/08/22 11:41:18 drh Exp $
+** $Id: btree.c,v 1.410 2007/08/23 02:47:53 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -1136,12 +1136,16 @@
   */
   if( (flags & BTREE_PRIVATE)==0
    && isMemdb==0
+   && (pSqlite==0 || (pSqlite->flags &SQLITE_Vtab)==0)
    && zFilename && zFilename[0]
    && sqlite3SharedCacheEnabled
   ){
     char *zFullPathname = (char *)sqlite3_malloc(pVfs->mxPathname);
     sqlite3_mutex *mutexShared;
     p->sharable = 1;
+    if( pSqlite ){
+      pSqlite->flags |= SQLITE_SharedCache;
+    }
     if( !zFullPathname ){
       sqlite3_free(p);
       return SQLITE_NOMEM;
diff --git a/src/func.c b/src/func.c
index 224f88f..7b981df 100644
--- a/src/func.c
+++ b/src/func.c
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.168 2007/08/21 19:33:56 drh Exp $
+** $Id: func.c,v 1.169 2007/08/23 02:47:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -807,14 +807,17 @@
     if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
       zOut[j++] = zStr[i];
     }else{
+      u8 *zOld;
       nOut += nRep - nPattern;
       if( nOut>=SQLITE_MAX_LENGTH ){
         sqlite3_result_error_toobig(context);
         sqlite3_free(zOut);
         return;
       }
+      zOld = zOut;
       zOut = sqlite3_realloc(zOut, (int)nOut);
       if( zOut==0 ){
+        sqlite3_free(zOld);
         return;
       }
       memcpy(&zOut[j], zRep, nRep);
diff --git a/src/loadext.c b/src/loadext.c
index a4c57c2..7d2340c 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -454,6 +454,7 @@
             "automatic extension loading failed: %s", zErrmsg);
       go = 0;
       rc = SQLITE_ERROR;
+      sqlite3_free(zErrmsg);
     }
   }
   return rc;
diff --git a/src/mem2.c b/src/mem2.c
index d9653ee..4b3c4f5 100644
--- a/src/mem2.c
+++ b/src/mem2.c
@@ -12,7 +12,7 @@
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite.  
 **
-** $Id: mem2.c,v 1.7 2007/08/22 22:04:37 drh Exp $
+** $Id: mem2.c,v 1.8 2007/08/23 02:47:53 drh Exp $
 */
 
 /*
@@ -59,9 +59,9 @@
 /*
 ** Each memory allocation looks like this:
 **
-**    ----------------------------------------------------------------
-**    |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |
-**    ----------------------------------------------------------------
+**  ------------------------------------------------------------------------
+**  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |
+**  ------------------------------------------------------------------------
 **
 ** The application code sees only a pointer to the allocation.  We have
 ** to back up from the allocation pointer to find the MemBlockHdr.  The
@@ -72,8 +72,9 @@
 struct MemBlockHdr {
   struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
   unsigned int iSize;                 /* Size of this allocation */
-  unsigned short nBacktrace;          /* Number of backtraces on this alloc */
-  unsigned short nBacktraceSlots;     /* Available backtrace slots */
+  unsigned char nBacktrace;           /* Number of backtraces on this alloc */
+  unsigned char nBacktraceSlots;      /* Available backtrace slots */
+  unsigned short nTitle;              /* Bytes of title; includes '\0' */
   unsigned int iForeGuard;            /* Guard word for sanity */
 };
 
@@ -125,6 +126,12 @@
   int nBacktrace;
 
   /*
+  ** Title text to insert in front of each block
+  */
+  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */
+  char zTitle[100];  /* The title text */
+
+  /*
   ** These values are used to simulate malloc failures.  When
   ** iFail is 1, simulate a malloc failures and reset the value
   ** to iReset.
@@ -252,6 +259,7 @@
 void *sqlite3_malloc(int nByte){
   struct MemBlockHdr *pHdr;
   void **pBt;
+  char *z;
   unsigned int *pInt;
   void *p;
   unsigned int totalSize;
@@ -269,7 +277,7 @@
   }
   nByte = (nByte+3)&~3;
   totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
-               mem.nBacktrace*sizeof(void*);
+               mem.nBacktrace*sizeof(void*) + mem.nTitle;
   if( mem.iFail>0 ){
     if( mem.iFail==1 ){
       p = 0;
@@ -290,7 +298,8 @@
     }
   }
   if( p ){
-    pBt = p;
+    z = p;
+    pBt = (void**)&z[mem.nTitle];
     pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
     pHdr->pNext = 0;
     pHdr->pPrev = mem.pLast;
@@ -302,6 +311,7 @@
     mem.pLast = pHdr;
     pHdr->iForeGuard = FOREGUARD;
     pHdr->nBacktraceSlots = mem.nBacktrace;
+    pHdr->nTitle = mem.nTitle;
     if( mem.nBacktrace ){
       void *aAddr[40];
       pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
@@ -309,6 +319,9 @@
     }else{
       pHdr->nBacktrace = 0;
     }
+    if( mem.nTitle ){
+      memcpy(z, mem.zTitle, mem.nTitle);
+    }
     pHdr->iSize = nByte;
     pInt = (unsigned int *)&pHdr[1];
     pInt[nByte/sizeof(unsigned int)] = REARGUARD;
@@ -329,6 +342,7 @@
 void sqlite3_free(void *pPrior){
   struct MemBlockHdr *pHdr;
   void **pBt;
+  char *z;
   if( pPrior==0 ){
     return;
   }
@@ -352,9 +366,11 @@
     assert( mem.pLast==pHdr );
     mem.pLast = pHdr->pPrev;
   }
-  memset(pBt, 0x2b, sizeof(void*)*pHdr->nBacktrace + sizeof(*pHdr) +
-                    pHdr->iSize + sizeof(unsigned int));
-  free(pBt);
+  z = (char*)pBt;
+  z -= pHdr->nTitle;
+  memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
+                  pHdr->iSize + sizeof(unsigned int) + pHdr->nTitle);
+  free(z);
   sqlite3_mutex_leave(mem.mutex);  
 }
 
@@ -403,6 +419,22 @@
 }
 
 /*
+** Set the title string for subsequent allocations.
+*/
+void sqlite3_memdebug_settitle(const char *zTitle){
+  int n = strlen(zTitle) + 1;
+  if( mem.mutex==0 ){
+    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
+  }
+  sqlite3_mutex_enter(mem.mutex);
+  if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
+  memcpy(mem.zTitle, zTitle, n);
+  mem.zTitle[n] = 0;
+  mem.nTitle = (n+3)&~3;
+  sqlite3_mutex_leave(mem.mutex);
+}
+
+/*
 ** Open the file indicated and write a log of all unfreed memory 
 ** allocations into that log.
 */
@@ -417,7 +449,9 @@
     return;
   }
   for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
-    fprintf(out, "**** %d bytes at %p ****\n", pHdr->iSize, &pHdr[1]);
+    char *z = (char*)pHdr;
+    z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
+    fprintf(out, "**** %d bytes at %p from %s ****\n", pHdr->iSize,&pHdr[1],z);
     if( pHdr->nBacktrace ){
       fflush(out);
       pBt = (void**)pHdr;
diff --git a/src/os_unix.c b/src/os_unix.c
index 75cf36e..eb7a66b 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -2657,6 +2657,10 @@
 /*
 ** Sleep for a little while.  Return the amount of time slept.
 ** The argument is the number of microseconds we want to sleep.
+** The return value is the number of microseconds of sleep actually
+** requested from the underlying operating system, a number which
+** might be greater than or equal to the argument, but not less
+** than the argument.
 */
 static int unixSleep(void *pNotUsed, int microseconds){
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
@@ -2665,7 +2669,7 @@
 #else
   int seconds = (microseconds+999999)/1000000;
   sleep(seconds);
-  return seconds;
+  return seconds*1000000;
 #endif
 }
 
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 6465245..b6b5668 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.237 2007/08/22 20:18:22 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.238 2007/08/23 02:47:53 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1389,8 +1389,11 @@
 ** (overwriting the previous values). Note that calls to [sqlite3_errcode()],
 ** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the
 ** results of future invocations.  Calls to API routines that do not return
-** an error code (examples: [sqlite3_data_count()] or [sqlite3_mprintf()]) do
-** not change the error code returned by this routine.
+** an error code (example: [sqlite3_data_count()]) do not
+** change the error code returned by this routine.  Interfaces that are
+** not associated with a specific database connection (examples:
+** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change
+** the return code.  
 **
 ** Assuming no other intervening sqlite3_* API calls are made, the error
 ** code returned by this function is associated with the same error as
@@ -1708,6 +1711,10 @@
 ** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()]
 ** or until the next call sqlite3_column_name() or sqlite3_column_name16()
 ** on the same column.
+**
+** If sqlite3_malloc() fails during the processing of either routine
+** (for example during a conversion from UTF-8 to UTF-16) then a
+** NULL pointer is returned.
 */
 const char *sqlite3_column_name(sqlite3_stmt*, int N);
 const void *sqlite3_column_name16(sqlite3_stmt*, int N);
@@ -2040,6 +2047,12 @@
 ** and blobs is freed automatically.  Do <b>not</b> pass the pointers returned
 ** [sqlite3_column_blob()], [sqlite_column_text()], etc. into 
 ** [sqlite3_free()].
+**
+** If a memory allocation error occurs during the evaluation of any
+** of these routines, a default value is returned.  The default value
+** is either the integer 0, the floating point number 0.0, or a NULL
+** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+** [SQLITE_NOMEM].
 */
 const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
 int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 4b6e01d..29da21f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.597 2007/08/22 11:41:18 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.598 2007/08/23 02:47:53 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -493,6 +493,8 @@
 #define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */
 
 #define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
+#define SQLITE_SharedCache    0x00080000  /* Cache sharing is enabled */
+#define SQLITE_Vtab           0x00100000  /* There exists a virtual table */
 
 /*
 ** Possible values for the sqlite.magic field.
diff --git a/src/test1.c b/src/test1.c
index 11ffb1e..198744c 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.270 2007/08/22 20:18:22 drh Exp $
+** $Id: test1.c,v 1.271 2007/08/23 02:47:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -186,18 +186,6 @@
 }
 
 /*
-** Decode a pointer to an sqlite3_stmt object.
-*/
-static int getFilePointer(
-  Tcl_Interp *interp, 
-  const char *zArg,  
-  sqlite3_file **ppFile
-){
-  *ppFile = (sqlite3_file*)sqlite3TextToPtr(zArg);
-  return TCL_OK;
-}
-
-/*
 ** Generate a text representation of a pointer that can be understood
 ** by the getDbPointer and getVmPointer routines above.
 **
diff --git a/src/test6.c b/src/test6.c
index 0abf235..93befb8 100644
--- a/src/test6.c
+++ b/src/test6.c
@@ -320,8 +320,6 @@
   sqlite_int64 iOfst
 ){
   CrashFile *pCrash = (CrashFile *)pFile;
-  sqlite3_int64 iSize;
-  WriteBuffer *pWrite;
 
   /* Check the file-size to see if this is a short-read */
   if( pCrash->iSize<(iOfst+iAmt) ){
@@ -346,9 +344,9 @@
     pCrash->iSize = iAmt+iOfst;
   }
   while( pCrash->iSize>pCrash->nData ){
-    char *zNew;
+    u8 *zNew;
     int nNew = (pCrash->nData*2) + 4096;
-    zNew = (char *)sqlite3_realloc(pCrash->zData, nNew);
+    zNew = sqlite3_realloc(pCrash->zData, nNew);
     if( !zNew ){
       return SQLITE_NOMEM;
     }
@@ -480,7 +478,7 @@
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAppData;
   int rc;
   CrashFile *pWrapper = (CrashFile *)pFile;
-  sqlite3_file *pReal = &pWrapper[1];
+  sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1];
 
   memset(pWrapper, 0, sizeof(CrashFile));
   rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags);
@@ -495,7 +493,7 @@
   }
   if( rc==SQLITE_OK ){
     pWrapper->nData = (4096 + pWrapper->iSize);
-    pWrapper->zData = (char *)sqlite3_malloc(pWrapper->nData);
+    pWrapper->zData = sqlite3_malloc(pWrapper->nData);
     if( pWrapper->zData ){
       memset(pWrapper->zData, 0, pWrapper->nData);
       rc = sqlite3OsRead(pReal, pWrapper->zData, pWrapper->iSize, 0); 
@@ -570,7 +568,6 @@
   int iDelay;
   const char *zCrashFile;
   int nCrashFile;
-  static struct crashAppData appData;
 
   static sqlite3_vfs crashVfs = {
     1,                  /* iVersion */
diff --git a/src/test8.c b/src/test8.c
index 28a49a7..8e7d50d 100644
--- a/src/test8.c
+++ b/src/test8.c
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test8.c,v 1.52 2007/08/21 10:44:16 drh Exp $
+** $Id: test8.c,v 1.53 2007/08/23 02:47:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -852,7 +852,7 @@
           "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1);
       zSep = ",";
     }
-    string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 0);
+    string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 1);
   }
 
   /* If apData[0] is an integer and nData==1 then do a DELETE */
diff --git a/src/test_malloc.c b/src/test_malloc.c
index 478c6c5..3952882 100644
--- a/src/test_malloc.c
+++ b/src/test_malloc.c
@@ -13,7 +13,7 @@
 ** This file contains code used to implement test interfaces to the
 ** memory allocation subsystem.
 **
-** $Id: test_malloc.c,v 1.3 2007/08/22 22:04:37 drh Exp $
+** $Id: test_malloc.c,v 1.4 2007/08/23 02:47:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -27,7 +27,16 @@
 static void pointerToText(void *p, char *z){
   static const char zHex[] = "0123456789abcdef";
   int i, k;
-  sqlite3_uint64 n = (sqlite3_uint64)p;
+  unsigned int u;
+  sqlite3_uint64 n;
+  if( sizeof(n)==sizeof(p) ){
+    memcpy(&n, &p, sizeof(p));
+  }else if( sizeof(u)==sizeof(p) ){
+    memcpy(&u, &p, sizeof(u));
+    n = u;
+  }else{
+    assert( 0 );
+  }
   for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){
     z[k] = zHex[n&0xf];
     n >>= 4;
@@ -46,6 +55,7 @@
 static int textToPointer(const char *z, void **pp){
   sqlite3_uint64 n = 0;
   int i;
+  unsigned int u;
   for(i=0; i<sizeof(void*)*2 && z[0]; i++){
     int v;
     v = hexToInt(*z++);
@@ -53,7 +63,14 @@
     n = n*16 + v;
   }
   if( *z!=0 ) return TCL_ERROR;
-  *pp = (void*)n;
+  if( sizeof(n)==sizeof(*pp) ){
+    memcpy(pp, &n, sizeof(n));
+  }else if( sizeof(u)==sizeof(*pp) ){
+    u = (unsigned int)n;
+    memcpy(pp, &u, sizeof(u));
+  }else{
+    assert( 0 );
+  }
   return TCL_OK;
 }
 
@@ -290,6 +307,38 @@
 
 
 /*
+** Usage:    sqlite3_memdebug_settitle TITLE
+**
+** Set a title string stored with each allocation.  The TITLE is
+** typically the name of the test that was running when the
+** allocation occurred.  The TITLE is stored with the allocation
+** and can be used to figure out which tests are leaking memory.
+**
+** Each title overwrite the previous.
+*/
+static int test_memdebug_settitle(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  const char *zTitle;
+  if( objc!=2 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
+    return TCL_ERROR;
+  }
+  zTitle = Tcl_GetString(objv[1]);
+#ifdef SQLITE_MEMDEBUG
+  {
+    extern int sqlite3_memdebug_settitle(const char*);
+    sqlite3_memdebug_settitle(zTitle);
+  }
+#endif
+  return TCL_OK;
+}
+
+
+/*
 ** Register commands with the TCL interpreter.
 */
 int Sqlitetest_malloc_Init(Tcl_Interp *interp){
@@ -306,6 +355,7 @@
      { "sqlite3_memdebug_dump",      test_memdebug_dump            },
      { "sqlite3_memdebug_fail",      test_memdebug_fail            },
      { "sqlite3_memdebug_pending",   test_memdebug_pending         },
+     { "sqlite3_memdebug_settitle",  test_memdebug_settitle        },
   };
   int i;
   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 85edcba..ff93ac5 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1007,6 +1007,8 @@
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   Mem *pColName;
   int n;
+  sqlite3 *db = p->db;
+
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqlite3_free(p->aColName);
   n = nResColumn*COLNAME_N;
@@ -1014,7 +1016,9 @@
   p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
   if( p->aColName==0 ) return;
   while( n-- > 0 ){
-    (pColName++)->flags = MEM_Null;
+    pColName->flags = MEM_Null;
+    pColName->db = db;
+    pColName++;
   }
 }
 
diff --git a/src/vtab.c b/src/vtab.c
index ac54516..09793ae 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.52 2007/08/22 02:56:44 drh Exp $
+** $Id: vtab.c,v 1.53 2007/08/23 02:47:53 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -167,12 +167,10 @@
   Table *pTable;        /* The new virtual table */
   sqlite3 *db;          /* Database connection */
 
-#if 0 /* FIX ME */
-  if( sqlite3ThreadDataReadOnly()->useSharedData ){
+  if( pParse->db->flags & SQLITE_SharedCache ){
     sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode");
     return;
   }
-#endif
 
   sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
   pTable = pParse->pNewTable;