SQLite4
Check-in [7091e990cd]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove sqlite4_mem_methods from sqlite.h.in. Other modifications so that src4.test works again.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7091e990cdf45e0ea8c1dabda4db745b75d50cbb
User & Date: dan 2013-05-21 20:08:24
Context
2013-05-22
17:40
Add simple OOM injection test to show that the sqlite4_mm based test infrastructure works. check-in: 3f1a52c793 user: dan tags: trunk
2013-05-21
20:08
Remove sqlite4_mem_methods from sqlite.h.in. Other modifications so that src4.test works again. check-in: 7091e990cd user: dan tags: trunk
18:19
Re-enable memory statistics and backtraces. check-in: 75b8ccc0a8 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to main.mk.

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
         callback.o complete.o ctime.o date.o delete.o env.o expr.o \
         fault.o fkey.o fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
................................................................................
  $(TOP)/src/lsm_unix.c \
  $(TOP)/src/lsm_varint.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \
  $(TOP)/src/mem.c \
  $(TOP)/src/mem0.c \
  $(TOP)/src/mem1.c \
  $(TOP)/src/mem2.c \
  $(TOP)/src/mem3.c \
  $(TOP)/src/mem5.c \
  $(TOP)/src/mutex.c \
  $(TOP)/src/mutex.h \
  $(TOP)/src/mutex_noop.c \
  $(TOP)/src/mutex_unix.c \







|







 







<







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
133
134
135
136
137
138
139

140
141
142
143
144
145
146
         callback.o complete.o ctime.o date.o delete.o env.o expr.o \
         fault.o fkey.o fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem.o mem0.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
................................................................................
  $(TOP)/src/lsm_unix.c \
  $(TOP)/src/lsm_varint.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \
  $(TOP)/src/mem.c \
  $(TOP)/src/mem0.c \

  $(TOP)/src/mem2.c \
  $(TOP)/src/mem3.c \
  $(TOP)/src/mem5.c \
  $(TOP)/src/mutex.c \
  $(TOP)/src/mutex.h \
  $(TOP)/src/mutex_noop.c \
  $(TOP)/src/mutex_unix.c \

Changes to src/env.c.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE4_THREADSAFE==1,     /* bFullMutex */
   0x7ffffffe,                /* mxStrlen */
   0,                         /* szLookaside */
   0,                         /* nLookaside */
   &sqlite4MMSystem,          /* pMM */
#if 0
   {0,0,0,0,0,0,0,0,0},       /* m */
#endif
   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   0,                         /* mxParserStack */
   &sqlite4BuiltinFactory,    /* pFactory */
   sqlite4OsRandomness,       /* xRandomness */







<
<
<







41
42
43
44
45
46
47



48
49
50
51
52
53
54
   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE4_THREADSAFE==1,     /* bFullMutex */
   0x7ffffffe,                /* mxStrlen */
   0,                         /* szLookaside */
   0,                         /* nLookaside */
   &sqlite4MMSystem,          /* pMM */



   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   0,                         /* mxParserStack */
   &sqlite4BuiltinFactory,    /* pFactory */
   sqlite4OsRandomness,       /* xRandomness */

Changes to src/sqlite.h.in.

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
/*
** CAPIREF: Run-time environment of a database connection
**
** Return the sqlite4_env object to which the database connection
** belongs.
*/
sqlite4_env *sqlite4_db_env(sqlite4*);

/*
** CAPIREF: Memory Allocation Routines
**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
**
** This object is used in only one place in the SQLite interface.
** A pointer to an instance of this object is the argument to
** [sqlite4_env_config()] when the configuration option is
** [SQLITE4_ENVCONFIG_MALLOC] or [SQLITE4_ENVCONFIG_GETMALLOC].  
** By creating an instance of this object
** and passing it to [sqlite4_env_config]([SQLITE4_ENVCONFIG_MALLOC])
** during configuration, an application can specify an alternative
** memory allocation subsystem for SQLite to use for all of its
** dynamic memory needs.
**
** Note that SQLite comes with several [built-in memory allocators]
** that are perfectly adequate for the overwhelming majority of applications
** and that this object is only useful to a tiny minority of applications
** with specialized memory allocation requirements.  This object is
** also used during testing of SQLite in order to specify an alternative
** memory allocator that simulates memory out-of-memory conditions in
** order to verify that SQLite recovers gracefully from such
** conditions.
**
** The xMalloc, xRealloc, and xFree methods must work like the
** malloc(), realloc() and free() functions from the standard C library.
** ^SQLite guarantees that the second argument to
** xRealloc is always a value returned by a prior call to xRoundup.
**
** xSize should return the allocated size of a memory allocation
** previously obtained from xMalloc or xRealloc.  The allocated size
** is always at least as big as the requested size but may be larger.
**
** The xRoundup method returns what would be the allocated size of
** a memory allocation given a particular requested size.  Most memory
** allocators round up memory allocations at least to the next multiple
** of 8.  Some allocators round up to a larger multiple or to a power of 2.
** Every memory allocation request coming in through [sqlite4_malloc()]
** or [sqlite4_realloc()] first calls xRoundup.  If xRoundup returns 0, 
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator.  (For example,
** it might allocate any require mutexes or initialize internal data
** structures.  The xShutdown method is invoked (indirectly) by
** [sqlite4_shutdown()] and should deallocate any resources acquired
** by xInit.  The pMemEnv pointer is used as the only parameter to
** xInit and xShutdown.
**
** SQLite holds the [SQLITE4_MUTEX_STATIC_MASTER] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe.  The
** xShutdown method is only called from [sqlite4_shutdown()] so it does
** not need to be threadsafe either.  For all other methods, SQLite
** holds the [SQLITE4_MUTEX_STATIC_MEM] mutex as long as the
** [SQLITE4_CONFIG_MEMSTATUS] configuration option is turned on (which
** it is by default) and so the methods are automatically serialized.
** However, if [SQLITE4_CONFIG_MEMSTATUS] is disabled, then the other
** methods must be threadsafe or else make their own arrangements for
** serialization.
**
** SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
*/
typedef struct sqlite4_mem_methods sqlite4_mem_methods;
struct sqlite4_mem_methods {
  void *(*xMalloc)(void*,sqlite4_size_t); /* Memory allocation function */
  void (*xFree)(void*,void*);             /* Free a prior allocation */
  void *(*xRealloc)(void*,void*,int);     /* Resize an allocation */
  sqlite4_size_t (*xSize)(void*,void*);   /* Return the size of an allocation */
  int (*xInit)(void*);                    /* Initialize the memory allocator */
  void (*xShutdown)(void*);               /* Deinitialize the allocator */
  void (*xBeginBenign)(void*);            /* Enter a benign malloc region */
  void (*xEndBenign)(void*);              /* Leave a benign malloc region */
  void *pMemEnv;                         /* 1st argument to all routines */
};


/*
** CAPIREF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite4_db_config()] interface.
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







729
730
731
732
733
734
735













































































736
737
738
739
740
741
742
/*
** CAPIREF: Run-time environment of a database connection
**
** Return the sqlite4_env object to which the database connection
** belongs.
*/
sqlite4_env *sqlite4_db_env(sqlite4*);














































































/*
** CAPIREF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite4_db_config()] interface.
**

Changes to src/sqliteInt.h.

2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
  int bMemstat;                     /* True to enable memory status */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int mxStrlen;                     /* Maximum string length */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite4_mm *pMM;                  /* Memory allocator for this environment */
#if 0
  sqlite4_mem_methods m;            /* Low-level memory allocation interface */
#endif
  sqlite4_mutex_methods mutex;      /* Low-level mutex interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  int mxParserStack;                /* maximum depth of the parser stack */
  KVFactory *pFactory;              /* List of factories */
  int (*xRandomness)(sqlite4_env*, int, unsigned char*);







<
<
<







2406
2407
2408
2409
2410
2411
2412



2413
2414
2415
2416
2417
2418
2419
  int bMemstat;                     /* True to enable memory status */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int mxStrlen;                     /* Maximum string length */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite4_mm *pMM;                  /* Memory allocator for this environment */



  sqlite4_mutex_methods mutex;      /* Low-level mutex interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  int mxParserStack;                /* maximum depth of the parser stack */
  KVFactory *pFactory;              /* List of factories */
  int (*xRandomness)(sqlite4_env*, int, unsigned char*);

Changes to src/update.c.

262
263
264
265
266
267
268


269
270

271
272
273
274
275
276
277
  hasFK = sqlite4FkRequired(pParse, pTab, aXRef);

  /* Allocate memory for the array aRegIdx[].  There is one entry in the
  ** array for each index associated with table being updated.  Fill in
  ** the value with a register number for indices that are to be used
  ** and with zero for unused indices.  */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}


  aRegIdx = sqlite4DbMallocZero(db, sizeof(Index*) * nIdx );
  if( aRegIdx==0 ) goto update_cleanup;


  /* Allocate registers for and populate the aRegIdx array. */
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( pIdx==pPk || hasFK || bChngPk ){
      aRegIdx[j] = ++pParse->nMem;
    }else{
      for(i=0; i<pIdx->nColumn; i++){







>
>
|
|
>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  hasFK = sqlite4FkRequired(pParse, pTab, aXRef);

  /* Allocate memory for the array aRegIdx[].  There is one entry in the
  ** array for each index associated with table being updated.  Fill in
  ** the value with a register number for indices that are to be used
  ** and with zero for unused indices.  */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  assert( nIdx>0 || isView );
  if( nIdx ){
    aRegIdx = sqlite4DbMallocZero(db, sizeof(Index*) * nIdx );
    if( aRegIdx==0 ) goto update_cleanup;
  }

  /* Allocate registers for and populate the aRegIdx array. */
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( pIdx==pPk || hasFK || bChngPk ){
      aRegIdx[j] = ++pParse->nMem;
    }else{
      for(i=0; i<pIdx->nColumn; i++){

Changes to test/auth.test.

2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221
      INSERT INTO v1chng VALUES(OLD.x,NEW.x);
    END;
    SELECT * FROM v1;
  }
} {115 117}
do_test auth-4.3 {
  set authargs {}

  execsql {
    UPDATE v1 SET x=1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE4_UPDATE v1     x  main {} \
  SQLITE4_SELECT {}     {} {}   v1 \







>







2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
      INSERT INTO v1chng VALUES(OLD.x,NEW.x);
    END;
    SELECT * FROM v1;
  }
} {115 117}
do_test auth-4.3 {
  set authargs {}
  breakpoint
  execsql {
    UPDATE v1 SET x=1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE4_UPDATE v1     x  main {} \
  SQLITE4_SELECT {}     {} {}   v1 \

Changes to test/fts5snippet.test.

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  1 utf16
} {
if {$DO_MALLOC_TEST || $enc=="utf16"} continue

  db close
  forcedelete test.db
  sqlite4 db test.db
  sqlite4_db_config_lookaside db 0 0 0
  db eval "PRAGMA encoding = \"$enc\""

  # Set variable $T to the test name prefix for this iteration of the loop.
  #
  set T "fts5snippet-$enc"
  
  ##########################################################################







<







116
117
118
119
120
121
122

123
124
125
126
127
128
129
  1 utf16
} {
if {$DO_MALLOC_TEST || $enc=="utf16"} continue

  db close
  forcedelete test.db
  sqlite4 db test.db

  db eval "PRAGMA encoding = \"$enc\""

  # Set variable $T to the test name prefix for this iteration of the loop.
  #
  set T "fts5snippet-$enc"
  
  ##########################################################################

Changes to test/malloc_common.tcl.

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
#   faultsim_delete_and_reopen
#
proc faultsim_save {args} { uplevel db_save $args }
proc faultsim_save_and_close {args} { uplevel db_save_and_close $args }
proc faultsim_restore {args} { uplevel db_restore $args }
proc faultsim_restore_and_reopen {args} { 
  uplevel db_restore_and_reopen $args 
  sqlite4_db_config_lookaside db 0 0 0
}
proc faultsim_delete_and_reopen {args} {
  uplevel db_delete_and_reopen $args 
  sqlite4_db_config_lookaside db 0 0 0
}

proc faultsim_integrity_check {{db db}} {
  set ic [$db eval { PRAGMA integrity_check }]
  if {$ic != "ok"} { error "Integrity check: $ic" }
}

................................................................................
        forcedelete test2.db
        forcedelete test2.db-journal
        forcedelete test2.db-wal
        if {[info exists ::mallocopts(-testdb)]} {
          copy_file $::mallocopts(-testdb) test.db
        }
        catch { sqlite4 db test.db }
        sqlite4_db_config_lookaside db 0 0 0
  
        # Execute any -tclprep and -sqlprep scripts.
        #
        if {[info exists ::mallocopts(-tclprep)]} {
          eval $::mallocopts(-tclprep)
        }
        if {[info exists ::mallocopts(-sqlprep)]} {







|



|







 







|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
#   faultsim_delete_and_reopen
#
proc faultsim_save {args} { uplevel db_save $args }
proc faultsim_save_and_close {args} { uplevel db_save_and_close $args }
proc faultsim_restore {args} { uplevel db_restore $args }
proc faultsim_restore_and_reopen {args} { 
  uplevel db_restore_and_reopen $args 
  #sqlite4_db_config_lookaside db 0 0 0
}
proc faultsim_delete_and_reopen {args} {
  uplevel db_delete_and_reopen $args 
  #sqlite4_db_config_lookaside db 0 0 0
}

proc faultsim_integrity_check {{db db}} {
  set ic [$db eval { PRAGMA integrity_check }]
  if {$ic != "ok"} { error "Integrity check: $ic" }
}

................................................................................
        forcedelete test2.db
        forcedelete test2.db-journal
        forcedelete test2.db-wal
        if {[info exists ::mallocopts(-testdb)]} {
          copy_file $::mallocopts(-testdb) test.db
        }
        catch { sqlite4 db test.db }
        #sqlite4_db_config_lookaside db 0 0 0
  
        # Execute any -tclprep and -sqlprep scripts.
        #
        if {[info exists ::mallocopts(-tclprep)]} {
          eval $::mallocopts(-tclprep)
        }
        if {[info exists ::mallocopts(-sqlprep)]} {

Changes to test/test_config.c.

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

#ifdef SQLITE4_DISABLE_LFS
  Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY);
#endif

#if 1 /* def SQLITE4_MEMDEBUG */
  Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE4_ENABLE_8_3_NAMES
  Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "1", TCL_GLOBAL_ONLY);







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

#ifdef SQLITE4_DISABLE_LFS
  Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY);
#endif

#if 0 /* def SQLITE4_MEMDEBUG */
  Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE4_ENABLE_8_3_NAMES
  Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "1", TCL_GLOBAL_ONLY);

Changes to test/test_malloc.c.

17
18
19
20
21
22
23

24
25
26
27
28
29
30
...
229
230
231
232
233
234
235

236


237
238
239
240
241
242
243
....
1120
1121
1122
1123
1124
1125
1126


1127
1128
1129
1130
1131
1132
1133
....
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275
1276
1277
....
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "testInt.h"


/*
** This structure is used to encapsulate the global state variables used 
** by malloc() fault simulation.
*/
static struct MemFault {
  int iCountdown;         /* Number of pending successes before a failure */
  int nRepeat;            /* Number of times to repeat the failure */
................................................................................
  if( rc==SQLITE4_OK ){
    memfault.isInstalled = 1;
  }
  return rc;
#endif
}


#ifdef SQLITE4_TEST



/*
** This function is implemented in test1.c. Returns a pointer to a static
** buffer containing the symbolic SQLite error code that corresponds to
** the least-significant 8-bits of the integer passed as an argument.
** For example:
**
................................................................................
#ifdef SQLITE4_ENABLE_MEMSYS3
  const sqlite4_mem_methods *sqlite4MemGetMemsys3(void);
  rc = sqlite4_env_config(0, SQLITE4_ENVCONFIG_MALLOC, sqlite4MemGetMemsys3());
#endif
  Tcl_SetResult(interp, (char *)sqlite4TestErrorName(rc), TCL_VOLATILE);
  return TCL_OK;
}



static sqlite4_mm *pMMDebug = 0;

/*
** tclcmd: test_mm_install ?debug? ?backtrace? ?stats?
*/
static int test_mm_install(
................................................................................
*/
int Sqlitetest_malloc_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     int clientData;
  } aObjCmd[] = {

     { "sqlite4_malloc",                 test_malloc                   ,0 },
     { "sqlite4_realloc",                test_realloc                  ,0 },
     { "sqlite4_free",                   test_free                     ,0 },
     { "memset",                         test_memset                   ,0 },
     { "memget",                         test_memget                   ,0 },
     { "sqlite4_memdebug_backtrace",     test_memdebug_backtrace       ,0 },
     { "sqlite4_memdebug_dump",          test_memdebug_dump            ,0 },
................................................................................
     { "sqlite4_db_status",              test_db_status                ,0 },
     { "install_malloc_faultsim",        test_install_malloc_faultsim  ,0 },
     { "sqlite4_env_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite4_envconfig_lookaside",    test_envconfig_lookaside      ,0 },
     { "sqlite4_config_error",           test_config_error             ,0 },
     { "sqlite4_db_config_lookaside",    test_db_config_lookaside      ,0 },
     { "sqlite4_install_memsys3",        test_install_memsys3          ,0 },


     { "test_mm_install",                test_mm_install               ,0 },
     { "test_mm_stat",                   test_mm_stat                  ,0 },
     { "test_mm_report",                 test_mm_report                ,0 },
  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    ClientData c = (ClientData)SQLITE4_INT_TO_PTR(aObjCmd[i].clientData);
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
  }
  return TCL_OK;
}
#endif







>







 







>

>
>







 







>
>







 







>







 







>













17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
....
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
....
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
....
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "testInt.h"

#if 0 
/*
** This structure is used to encapsulate the global state variables used 
** by malloc() fault simulation.
*/
static struct MemFault {
  int iCountdown;         /* Number of pending successes before a failure */
  int nRepeat;            /* Number of times to repeat the failure */
................................................................................
  if( rc==SQLITE4_OK ){
    memfault.isInstalled = 1;
  }
  return rc;
#endif
}

#endif
#ifdef SQLITE4_TEST

#if 0

/*
** This function is implemented in test1.c. Returns a pointer to a static
** buffer containing the symbolic SQLite error code that corresponds to
** the least-significant 8-bits of the integer passed as an argument.
** For example:
**
................................................................................
#ifdef SQLITE4_ENABLE_MEMSYS3
  const sqlite4_mem_methods *sqlite4MemGetMemsys3(void);
  rc = sqlite4_env_config(0, SQLITE4_ENVCONFIG_MALLOC, sqlite4MemGetMemsys3());
#endif
  Tcl_SetResult(interp, (char *)sqlite4TestErrorName(rc), TCL_VOLATILE);
  return TCL_OK;
}

#endif

static sqlite4_mm *pMMDebug = 0;

/*
** tclcmd: test_mm_install ?debug? ?backtrace? ?stats?
*/
static int test_mm_install(
................................................................................
*/
int Sqlitetest_malloc_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     int clientData;
  } aObjCmd[] = {
#if 0
     { "sqlite4_malloc",                 test_malloc                   ,0 },
     { "sqlite4_realloc",                test_realloc                  ,0 },
     { "sqlite4_free",                   test_free                     ,0 },
     { "memset",                         test_memset                   ,0 },
     { "memget",                         test_memget                   ,0 },
     { "sqlite4_memdebug_backtrace",     test_memdebug_backtrace       ,0 },
     { "sqlite4_memdebug_dump",          test_memdebug_dump            ,0 },
................................................................................
     { "sqlite4_db_status",              test_db_status                ,0 },
     { "install_malloc_faultsim",        test_install_malloc_faultsim  ,0 },
     { "sqlite4_env_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite4_envconfig_lookaside",    test_envconfig_lookaside      ,0 },
     { "sqlite4_config_error",           test_config_error             ,0 },
     { "sqlite4_db_config_lookaside",    test_db_config_lookaside      ,0 },
     { "sqlite4_install_memsys3",        test_install_memsys3          ,0 },
#endif

     { "test_mm_install",                test_mm_install               ,0 },
     { "test_mm_stat",                   test_mm_stat                  ,0 },
     { "test_mm_report",                 test_mm_report                ,0 },
  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    ClientData c = (ClientData)SQLITE4_INT_TO_PTR(aObjCmd[i].clientData);
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
  }
  return TCL_OK;
}
#endif

Changes to test/tester.tcl.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
359
360
361
362
363
364
365
366
367
368
369





370
371
372
373
374

375
376
377
378
379
380
381
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
...
770
771
772
773
774
775
776


777

778
779
780
781
782
783
784
...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
set tcl_precision 15
#sqlite4_test_control_pending_byte 0x0010000

test_mm_install stats debug


# If the pager codec is available, create a wrapper for the [sqlite4] 
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
#     sqlite4 db test.db
#
# becomes
................................................................................
      default {
        lappend leftover $a
      }
    }
  }
  set argv $leftover

  # Install the malloc layer used to inject OOM errors. And the 'automatic'
  # extensions. This only needs to be done once for the process.
  #
  sqlite4_shutdown 





  # install_malloc_faultsim 1 
  if {$cmdlinearg(malloctrace)} { testmem install }
  kvwrap install
  sqlite4_initialize
  #autoinstall_test_functions


  # If the --binarylog option was specified, create the logging VFS. This
  # call installs the new VFS as the default for all SQLite connections.
  #
  if {$cmdlinearg(binarylog)} {
    vfslog new binarylog {} vfslog.bin
  }
................................................................................
}
reset_db

# Abort early if this script has been run before.
#
if {[info exists TC(count)]} return

# Make sure memory statistics are enabled.
#
sqlite4_env_config_memstatus 1

# Initialize the test counters and set up commands to access them.
# Or, if this is a slave interpreter, set up aliases to write the
# counters in the parent interpreter.
#
if {0==[info exists ::SLAVE]} {
  set TC(errors)    0
  set TC(count)     0
................................................................................
#
proc do_test {name cmd expected} {

  global argv cmdlinearg

  fix_testname name

  sqlite4_memdebug_settitle $name

#  if {[llength $argv]==0} { 
#    set go 1
#  } else {
#    set go 0
#    foreach pattern $argv {
#      if {[string match $pattern $name]} {
................................................................................
  set nUnit [test_mm_stat units]
  if {$nOut!=0 || $nUnit!=0} {
    puts "Unfreed memory: $nOut bytes in $nUnit allocations"
  } else {
    puts "All memory allocations freed - no leaks"
  }
  show_memstats


  test_mm_report malloc.txt


#  if {[lindex [sqlite4_env_status SQLITE4_ENVSTATUS_MALLOC_COUNT 0] 1]>0 ||
#              [sqlite4_memory_used]>0} {
#    puts "Unfreed memory: [sqlite4_memory_used] bytes in\
#         [lindex [sqlite4_env_status SQLITE4_ENVSTATUS_MALLOC_COUNT 0] 1] allocations"
#    incr nErr
#    ifcapable memdebug||mem5||(mem3&&debug) {
................................................................................
#    }
#  }
  #puts "Maximum memory usage: [sqlite4_memory_highwater 1] bytes"
  #puts "Current memory usage: [sqlite4_memory_highwater] bytes"
  #if {[info commands sqlite4_memdebug_malloc_count] ne ""} {
  #  puts "Number of malloc()  : [sqlite4_memdebug_malloc_count] calls"
  #}
  if {$::cmdlinearg(malloctrace)} {
    puts "Writing malloc() report to malloc.txt..."
    testmem report malloc.txt
  }
  foreach f [glob -nocomplain test.db-*-journal] {
    forcedelete $f
  }
  foreach f [glob -nocomplain test.db-mj*] {
    forcedelete $f
  }
  exit [expr {$nErr>0}]







<
<







 







|
|
<

>
>
>
>
>

<

<

>







 







<
<
<
<







 







|







 







>
>
|
>







 







<
<
<
<







81
82
83
84
85
86
87


88
89
90
91
92
93
94
...
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372

373

374
375
376
377
378
379
380
381
382
...
405
406
407
408
409
410
411




412
413
414
415
416
417
418
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
...
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
...
792
793
794
795
796
797
798




799
800
801
802
803
804
805
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
set tcl_precision 15
#sqlite4_test_control_pending_byte 0x0010000




# If the pager codec is available, create a wrapper for the [sqlite4] 
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
#     sqlite4 db test.db
#
# becomes
................................................................................
      default {
        lappend leftover $a
      }
    }
  }
  set argv $leftover

  # Install the various malloc wrappers. This only needs to be done 
  # once for the process.

  sqlite4_shutdown 
  set mm stats
  if {$cmdlinearg(malloctrace)} { lappend mm debug }
  test_mm_install {*}$mm


  # install_malloc_faultsim 1 

  kvwrap install

  #autoinstall_test_functions
  sqlite4_initialize

  # If the --binarylog option was specified, create the logging VFS. This
  # call installs the new VFS as the default for all SQLite connections.
  #
  if {$cmdlinearg(binarylog)} {
    vfslog new binarylog {} vfslog.bin
  }
................................................................................
}
reset_db

# Abort early if this script has been run before.
#
if {[info exists TC(count)]} return





# Initialize the test counters and set up commands to access them.
# Or, if this is a slave interpreter, set up aliases to write the
# counters in the parent interpreter.
#
if {0==[info exists ::SLAVE]} {
  set TC(errors)    0
  set TC(count)     0
................................................................................
#
proc do_test {name cmd expected} {

  global argv cmdlinearg

  fix_testname name

  #sqlite4_memdebug_settitle $name

#  if {[llength $argv]==0} { 
#    set go 1
#  } else {
#    set go 0
#    foreach pattern $argv {
#      if {[string match $pattern $name]} {
................................................................................
  set nUnit [test_mm_stat units]
  if {$nOut!=0 || $nUnit!=0} {
    puts "Unfreed memory: $nOut bytes in $nUnit allocations"
  } else {
    puts "All memory allocations freed - no leaks"
  }
  show_memstats
  if {$::cmdlinearg(malloctrace)} { 
    puts "Writing malloc() report to malloc.txt..."
    test_mm_report malloc.txt
  }

#  if {[lindex [sqlite4_env_status SQLITE4_ENVSTATUS_MALLOC_COUNT 0] 1]>0 ||
#              [sqlite4_memory_used]>0} {
#    puts "Unfreed memory: [sqlite4_memory_used] bytes in\
#         [lindex [sqlite4_env_status SQLITE4_ENVSTATUS_MALLOC_COUNT 0] 1] allocations"
#    incr nErr
#    ifcapable memdebug||mem5||(mem3&&debug) {
................................................................................
#    }
#  }
  #puts "Maximum memory usage: [sqlite4_memory_highwater 1] bytes"
  #puts "Current memory usage: [sqlite4_memory_highwater] bytes"
  #if {[info commands sqlite4_memdebug_malloc_count] ne ""} {
  #  puts "Number of malloc()  : [sqlite4_memdebug_malloc_count] calls"
  #}




  foreach f [glob -nocomplain test.db-*-journal] {
    forcedelete $f
  }
  foreach f [glob -nocomplain test.db-mj*] {
    forcedelete $f
  }
  exit [expr {$nErr>0}]

Changes to test/tkt-9d68c883.test.

10
11
12
13
14
15
16





17
18
19
20
21
22
23
#***********************************************************************
# This file tests that bug  9d68c883132c8e9ffcd5b0c148c990807b5df1b7
# is fixed.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl






do_test tkt-9d68c88-1.1 {
  execsql {
    PRAGMA page_size = 1024;
    PRAGMA auto_vacuum = 2;
    CREATE TABLE t3(x);
    CREATE TABLE t4(x);







>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#***********************************************************************
# This file tests that bug  9d68c883132c8e9ffcd5b0c148c990807b5df1b7
# is fixed.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !memdebug {
  finish_test
  return
}

do_test tkt-9d68c88-1.1 {
  execsql {
    PRAGMA page_size = 1024;
    PRAGMA auto_vacuum = 2;
    CREATE TABLE t3(x);
    CREATE TABLE t4(x);

Changes to test/where8.test.

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# At one point the following tests provoked an invalid write error (writing
# to memory that had already been freed). It was not possible to demonstrate
# that this bug could cause a query to return bad data.
# 
do_test where8-5.1 {
  db close
  sqlite4 db test.db
  sqlite4_db_config_lookaside db 0 0 0
  execsql {
    CREATE TABLE tA(
      a, b, c, d, e, f, g, h, 
      i, j, k, l, m, n, o, p
    );
  }
  execsql {







|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# At one point the following tests provoked an invalid write error (writing
# to memory that had already been freed). It was not possible to demonstrate
# that this bug could cause a query to return bad data.
# 
do_test where8-5.1 {
  db close
  sqlite4 db test.db
  #sqlite4_db_config_lookaside db 0 0 0
  execsql {
    CREATE TABLE tA(
      a, b, c, d, e, f, g, h, 
      i, j, k, l, m, n, o, p
    );
  }
  execsql {