/ Check-in [21f6b310]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment: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)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 21f6b31097692171c6493e6ca6de6acbd62dc595
User & Date: drh 2007-08-23 02:47:53
Context
2007-08-23
02:50
Change names of constants in lemon.c to work around name conflicts on Solaris. Ticket #2583. (CVS 4274) check-in: e4e74cd0 user: drh tags: trunk
02:47
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) check-in: 21f6b310 user: drh tags: trunk
2007-08-22
22:04
All of the malloc test cases run. Still seeing failures in malloc4.test. (CVS 4272) check-in: 205d0b88 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144



1145
1146
1147
1148
1149
1150
1151
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.409 2007/08/22 11:41:18 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( (flags & BTREE_PRIVATE)==0
   && isMemdb==0

   && zFilename && zFilename[0]
   && sqlite3SharedCacheEnabled
  ){
    char *zFullPathname = (char *)sqlite3_malloc(pVfs->mxPathname);
    sqlite3_mutex *mutexShared;
    p->sharable = 1;



    if( !zFullPathname ){
      sqlite3_free(p);
      return SQLITE_NOMEM;
    }
    sqlite3OsFullPathname(pVfs, zFilename, zFullPathname);
    mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
    sqlite3_mutex_enter(mutexShared);







|







 







>






>
>
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $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.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  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;
    }
    sqlite3OsFullPathname(pVfs, zFilename, zFullPathname);
    mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
    sqlite3_mutex_enter(mutexShared);

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
803
804
805
806
807
808
809

810
811
812
813
814
815

816
817

818
819
820
821
822
823
824
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** 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 $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

................................................................................
    return;
  }
  loopLimit = nStr - nPattern;  
  for(i=j=0; i<=loopLimit; i++){
    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
      zOut[j++] = zStr[i];
    }else{

      nOut += nRep - nPattern;
      if( nOut>=SQLITE_MAX_LENGTH ){
        sqlite3_result_error_toobig(context);
        sqlite3_free(zOut);
        return;
      }

      zOut = sqlite3_realloc(zOut, (int)nOut);
      if( zOut==0 ){

        return;
      }
      memcpy(&zOut[j], zRep, nRep);
      j += nRep;
      i += nPattern-1;
    }
  }







|







 







>






>


>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.169 2007/08/23 02:47:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

................................................................................
    return;
  }
  loopLimit = nStr - nPattern;  
  for(i=j=0; i<=loopLimit; i++){
    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);
      j += nRep;
      i += nPattern-1;
    }
  }

Changes to src/loadext.c.

450
451
452
453
454
455
456

457
458
459
460
461
462
    }
    sqlite3_mutex_leave(mutex);
    if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
      sqlite3Error(db, SQLITE_ERROR,
            "automatic extension loading failed: %s", zErrmsg);
      go = 0;
      rc = SQLITE_ERROR;

    }
  }
  return rc;
}

#endif /* SQLITE_OMIT_LOAD_EXTENSION */







>






450
451
452
453
454
455
456
457
458
459
460
461
462
463
    }
    sqlite3_mutex_leave(mutex);
    if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
      sqlite3Error(db, SQLITE_ERROR,
            "automatic extension loading failed: %s", zErrmsg);
      go = 0;
      rc = SQLITE_ERROR;
      sqlite3_free(zErrmsg);
    }
  }
  return rc;
}

#endif /* SQLITE_OMIT_LOAD_EXTENSION */

Changes to src/mem2.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
...
120
121
122
123
124
125
126






127
128
129
130
131
132
133
...
248
249
250
251
252
253
254

255
256
257
258
259
260
261
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311



312
313
314
315
316
317
318
...
325
326
327
328
329
330
331

332
333
334
335
336
337
338
...
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364
...
397
398
399
400
401
402
403
















404
405
406
407
408
409
410
...
413
414
415
416
417
418
419


420
421
422
423
424
425
426
427
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 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 $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/
................................................................................
# define backtrace(A,B) 0
# define backtrace_symbols_fd(A,B,C)
#endif

/*
** Each memory allocation looks like this:
**
**    ----------------------------------------------------------------
**    |  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
** MemBlockHdr tells us the size of the allocation and the number of
** backtrace pointers.  There is also a guard word at the end of the
** MemBlockHdr.
*/
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 int iForeGuard;            /* Guard word for sanity */
};

/*
** Guard words
*/
#define FOREGUARD 0x80F5E153
................................................................................
  struct MemBlockHdr *pLast;
  
  /*
  ** The number of levels of backtrace to save in new allocations.
  */
  int nBacktrace;







  /*
  ** These values are used to simulate malloc failures.  When
  ** iFail is 1, simulate a malloc failures and reset the value
  ** to iReset.
  */
  int iFail;    /* Decrement and fail malloc when this is 1 */
  int iReset;   /* When malloc fails set iiFail to this value */
................................................................................

/*
** Allocate nByte bytes of memory.
*/
void *sqlite3_malloc(int nByte){
  struct MemBlockHdr *pHdr;
  void **pBt;

  unsigned int *pInt;
  void *p;
  unsigned int totalSize;

  if( nByte<=0 ){
    return 0;
  }
................................................................................
  sqlite3_mutex_enter(mem.mutex);
  assert( mem.disallow==0 );
  if( mem.nowUsed+nByte>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nByte);
  }
  nByte = (nByte+3)&~3;
  totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
               mem.nBacktrace*sizeof(void*);
  if( mem.iFail>0 ){
    if( mem.iFail==1 ){
      p = 0;
      mem.iFail = mem.iReset;
      if( mem.iFailCnt==0 ){
        sqlite3MemsysFailed();  /* A place to set a breakpoint */
      }
................................................................................
    p = malloc(totalSize);
    if( p==0 ){
      sqlite3MemsysAlarm(nByte);
      p = malloc(totalSize);
    }
  }
  if( p ){
    pBt = p;

    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
    pHdr->pNext = 0;
    pHdr->pPrev = mem.pLast;
    if( mem.pLast ){
      mem.pLast->pNext = pHdr;
    }else{
      mem.pFirst = pHdr;
    }
    mem.pLast = pHdr;
    pHdr->iForeGuard = FOREGUARD;
    pHdr->nBacktraceSlots = mem.nBacktrace;

    if( mem.nBacktrace ){
      void *aAddr[40];
      pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
    }else{
      pHdr->nBacktrace = 0;
    }



    pHdr->iSize = nByte;
    pInt = (unsigned int *)&pHdr[1];
    pInt[nByte/sizeof(unsigned int)] = REARGUARD;
    memset(pInt, 0x65, nByte);
    mem.nowUsed += nByte;
    if( mem.nowUsed>mem.mxUsed ){
      mem.mxUsed = mem.nowUsed;
................................................................................

/*
** Free memory.
*/
void sqlite3_free(void *pPrior){
  struct MemBlockHdr *pHdr;
  void **pBt;

  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  pHdr = sqlite3MemsysGetHeader(pPrior);
  pBt = (void**)pHdr;
  pBt -= pHdr->nBacktraceSlots;
................................................................................
  if( pHdr->pNext ){
    assert( pHdr->pNext->pPrev==pHdr );
    pHdr->pNext->pPrev = pHdr->pPrev;
  }else{
    assert( mem.pLast==pHdr );
    mem.pLast = pHdr->pPrev;
  }


  memset(pBt, 0x2b, sizeof(void*)*pHdr->nBacktrace + sizeof(*pHdr) +
                    pHdr->iSize + sizeof(unsigned int));
  free(pBt);
  sqlite3_mutex_leave(mem.mutex);  
}

/*
** Change the size of an existing memory allocation.
**
** For this debugging implementation, we *always* make a copy of the
................................................................................
*/
void sqlite3_memdebug_backtrace(int depth){
  if( depth<0 ){ depth = 0; }
  if( depth>20 ){ depth = 20; }
  depth = (depth+1)&0xfe;
  mem.nBacktrace = depth;
}

















/*
** Open the file indicated and write a log of all unfreed memory 
** allocations into that log.
*/
void sqlite3_memdebug_dump(const char *zFilename){
  FILE *out;
................................................................................
  out = fopen(zFilename, "w");
  if( out==0 ){
    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                    zFilename);
    return;
  }
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){


    fprintf(out, "**** %d bytes at %p ****\n", pHdr->iSize, &pHdr[1]);
    if( pHdr->nBacktrace ){
      fflush(out);
      pBt = (void**)pHdr;
      pBt -= pHdr->nBacktraceSlots;
      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
      fprintf(out, "\n");
    }







|







 







|
|
|










|
|
>







 







>
>
>
>
>
>







 







>







 







|







 







|
>











>







>
>
>







 







>







 







>
>
|
|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
...
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.8 2007/08/23 02:47:53 drh Exp $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/
................................................................................
# define backtrace(A,B) 0
# define backtrace_symbols_fd(A,B,C)
#endif

/*
** Each memory allocation looks like this:
**
**  ------------------------------------------------------------------------
**  | 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
** MemBlockHdr tells us the size of the allocation and the number of
** backtrace pointers.  There is also a guard word at the end of the
** MemBlockHdr.
*/
struct MemBlockHdr {
  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
  unsigned int iSize;                 /* Size of this allocation */
  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 */
};

/*
** Guard words
*/
#define FOREGUARD 0x80F5E153
................................................................................
  struct MemBlockHdr *pLast;
  
  /*
  ** The number of levels of backtrace to save in new allocations.
  */
  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.
  */
  int iFail;    /* Decrement and fail malloc when this is 1 */
  int iReset;   /* When malloc fails set iiFail to this value */
................................................................................

/*
** Allocate nByte bytes of memory.
*/
void *sqlite3_malloc(int nByte){
  struct MemBlockHdr *pHdr;
  void **pBt;
  char *z;
  unsigned int *pInt;
  void *p;
  unsigned int totalSize;

  if( nByte<=0 ){
    return 0;
  }
................................................................................
  sqlite3_mutex_enter(mem.mutex);
  assert( mem.disallow==0 );
  if( mem.nowUsed+nByte>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nByte);
  }
  nByte = (nByte+3)&~3;
  totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
               mem.nBacktrace*sizeof(void*) + mem.nTitle;
  if( mem.iFail>0 ){
    if( mem.iFail==1 ){
      p = 0;
      mem.iFail = mem.iReset;
      if( mem.iFailCnt==0 ){
        sqlite3MemsysFailed();  /* A place to set a breakpoint */
      }
................................................................................
    p = malloc(totalSize);
    if( p==0 ){
      sqlite3MemsysAlarm(nByte);
      p = malloc(totalSize);
    }
  }
  if( p ){
    z = p;
    pBt = (void**)&z[mem.nTitle];
    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
    pHdr->pNext = 0;
    pHdr->pPrev = mem.pLast;
    if( mem.pLast ){
      mem.pLast->pNext = pHdr;
    }else{
      mem.pFirst = pHdr;
    }
    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;
      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
    }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;
    memset(pInt, 0x65, nByte);
    mem.nowUsed += nByte;
    if( mem.nowUsed>mem.mxUsed ){
      mem.mxUsed = mem.nowUsed;
................................................................................

/*
** Free memory.
*/
void sqlite3_free(void *pPrior){
  struct MemBlockHdr *pHdr;
  void **pBt;
  char *z;
  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  pHdr = sqlite3MemsysGetHeader(pPrior);
  pBt = (void**)pHdr;
  pBt -= pHdr->nBacktraceSlots;
................................................................................
  if( pHdr->pNext ){
    assert( pHdr->pNext->pPrev==pHdr );
    pHdr->pNext->pPrev = pHdr->pPrev;
  }else{
    assert( mem.pLast==pHdr );
    mem.pLast = pHdr->pPrev;
  }
  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);  
}

/*
** Change the size of an existing memory allocation.
**
** For this debugging implementation, we *always* make a copy of the
................................................................................
*/
void sqlite3_memdebug_backtrace(int depth){
  if( depth<0 ){ depth = 0; }
  if( depth>20 ){ depth = 20; }
  depth = (depth+1)&0xfe;
  mem.nBacktrace = depth;
}

/*
** 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.
*/
void sqlite3_memdebug_dump(const char *zFilename){
  FILE *out;
................................................................................
  out = fopen(zFilename, "w");
  if( out==0 ){
    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                    zFilename);
    return;
  }
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    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;
      pBt -= pHdr->nBacktraceSlots;
      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
      fprintf(out, "\n");
    }

Changes to src/os_unix.c.

2653
2654
2655
2656
2657
2658
2659




2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
  return SQLITE_OK;
}


/*
** Sleep for a little while.  Return the amount of time slept.
** The argument is the number of microseconds we want to sleep.




*/
static int unixSleep(void *pNotUsed, int microseconds){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
  usleep(microseconds);
  return microseconds;
#else
  int seconds = (microseconds+999999)/1000000;
  sleep(seconds);
  return seconds;
#endif
}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/







>
>
>
>








|







2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
  return SQLITE_OK;
}


/*
** 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
  usleep(microseconds);
  return microseconds;
#else
  int seconds = (microseconds+999999)/1000000;
  sleep(seconds);
  return seconds*1000000;
#endif
}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
1385
1386
1387
1388
1389
1390
1391
1392
1393



1394
1395
1396
1397
1398
1399
1400
....
1704
1705
1706
1707
1708
1709
1710




1711
1712
1713
1714
1715
1716
1717
....
2036
2037
2038
2039
2040
2041
2042






2043
2044
2045
2046
2047
2048
2049
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** 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 $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** interface functions.
**
** Calls to many sqlite3_* functions set the error code and string returned
** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()]
** (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.



**
** Assuming no other intervening sqlite3_* API calls are made, the error
** code returned by this function is associated with the same error as
** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()].
*/
int sqlite3_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
................................................................................
** The second parameter is the column number.  The left-most column is
** number 0.
**
** The returned string pointer is valid until either the 
** [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.




*/
const char *sqlite3_column_name(sqlite3_stmt*, int N);
const void *sqlite3_column_name16(sqlite3_stmt*, int N);

/*
** CAPI3REF: Source Of Data In A Query Result
**
................................................................................
**
** The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called.  The memory space used to hold strings
** and blobs is freed automatically.  Do <b>not</b> pass the pointers returned
** [sqlite3_column_blob()], [sqlite_column_text()], etc. into 
** [sqlite3_free()].






*/
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);







|







 







|
|
>
>
>







 







>
>
>
>







 







>
>
>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
....
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
....
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.238 2007/08/23 02:47:53 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** interface functions.
**
** Calls to many sqlite3_* functions set the error code and string returned
** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()]
** (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 (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
** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()].
*/
int sqlite3_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
................................................................................
** The second parameter is the column number.  The left-most column is
** number 0.
**
** The returned string pointer is valid until either the 
** [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);

/*
** CAPI3REF: Source Of Data In A Query Result
**
................................................................................
**
** The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called.  The memory space used to hold strings
** 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);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
489
490
491
492
493
494
495


496
497
498
499
500
501
502
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.597 2007/08/22 11:41:18 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"


#if defined(SQLITE_TCL) || defined(TCLSH)
................................................................................
#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
#define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */

#define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */



/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */







|







 







>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.598 2007/08/23 02:47:53 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"


#if defined(SQLITE_TCL) || defined(TCLSH)
................................................................................
#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
#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.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** 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 $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  const char *zArg,  
  sqlite3_stmt **ppStmt
){
  *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg);
  return TCL_OK;
}

/*
** 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.
**
** The problem is, on some machines (Solaris) if you do a printf with
** "%p" you cannot turn around and do a scanf with the same "%p" and
** get your pointer back.  You have to prepend a "0x" before it will







|







 







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







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
181
182
183
184
185
186
187












188
189
190
191
192
193
194
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.271 2007/08/23 02:47:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  const char *zArg,  
  sqlite3_stmt **ppStmt
){
  *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg);
  return TCL_OK;
}













/*
** Generate a text representation of a pointer that can be understood
** by the getDbPointer and getVmPointer routines above.
**
** The problem is, on some machines (Solaris) if you do a printf with
** "%p" you cannot turn around and do a scanf with the same "%p" and
** get your pointer back.  You have to prepend a "0x" before it will

Changes to src/test6.c.

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
static int cfRead(
  sqlite3_file *pFile, 
  void *zBuf, 
  int iAmt, 
  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) ){
    return SQLITE_IOERR_SHORT_READ;
  }

  memcpy(zBuf, &pCrash->zData[iOfst], iAmt);
................................................................................
  sqlite_int64 iOfst
){
  CrashFile *pCrash = (CrashFile *)pFile;
  if( iAmt+iOfst>pCrash->iSize ){
    pCrash->iSize = iAmt+iOfst;
  }
  while( pCrash->iSize>pCrash->nData ){
    char *zNew;
    int nNew = (pCrash->nData*2) + 4096;
    zNew = (char *)sqlite3_realloc(pCrash->zData, nNew);
    if( !zNew ){
      return SQLITE_NOMEM;
    }
    memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData);
    pCrash->nData = nNew;
    pCrash->zData = zNew;
  }
................................................................................
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAppData;
  int rc;
  CrashFile *pWrapper = (CrashFile *)pFile;
  sqlite3_file *pReal = &pWrapper[1];

  memset(pWrapper, 0, sizeof(CrashFile));
  rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags);

  if( rc==SQLITE_OK ){
    i64 iSize;
    pWrapper->pMethod = &CrashFileVtab;
................................................................................
    pWrapper->zName = (char *)zName;
    pWrapper->pRealFile = pReal;
    rc = sqlite3OsFileSize(pReal, &iSize);
    pWrapper->iSize = (int)iSize;
  }
  if( rc==SQLITE_OK ){
    pWrapper->nData = (4096 + pWrapper->iSize);
    pWrapper->zData = (char *)sqlite3_malloc(pWrapper->nData);
    if( pWrapper->zData ){
      memset(pWrapper->zData, 0, pWrapper->nData);
      rc = sqlite3OsRead(pReal, pWrapper->zData, pWrapper->iSize, 0); 
    }else{
      rc = SQLITE_NOMEM;
    }
  }
................................................................................
  int objc,
  Tcl_Obj *CONST objv[]
){
  int i;
  int iDelay;
  const char *zCrashFile;
  int nCrashFile;
  static struct crashAppData appData;

  static sqlite3_vfs crashVfs = {
    1,                  /* iVersion */
    0,                  /* szOsFile */
    0,                  /* mxPathname */
    0,                  /* nRef */
    0,                  /* vfsMutex */







<
<







 







|

|







 







|







 







|







 







<







316
317
318
319
320
321
322


323
324
325
326
327
328
329
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
...
564
565
566
567
568
569
570

571
572
573
574
575
576
577
static int cfRead(
  sqlite3_file *pFile, 
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  CrashFile *pCrash = (CrashFile *)pFile;



  /* Check the file-size to see if this is a short-read */
  if( pCrash->iSize<(iOfst+iAmt) ){
    return SQLITE_IOERR_SHORT_READ;
  }

  memcpy(zBuf, &pCrash->zData[iOfst], iAmt);
................................................................................
  sqlite_int64 iOfst
){
  CrashFile *pCrash = (CrashFile *)pFile;
  if( iAmt+iOfst>pCrash->iSize ){
    pCrash->iSize = iAmt+iOfst;
  }
  while( pCrash->iSize>pCrash->nData ){
    u8 *zNew;
    int nNew = (pCrash->nData*2) + 4096;
    zNew = sqlite3_realloc(pCrash->zData, nNew);
    if( !zNew ){
      return SQLITE_NOMEM;
    }
    memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData);
    pCrash->nData = nNew;
    pCrash->zData = zNew;
  }
................................................................................
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAppData;
  int rc;
  CrashFile *pWrapper = (CrashFile *)pFile;
  sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1];

  memset(pWrapper, 0, sizeof(CrashFile));
  rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags);

  if( rc==SQLITE_OK ){
    i64 iSize;
    pWrapper->pMethod = &CrashFileVtab;
................................................................................
    pWrapper->zName = (char *)zName;
    pWrapper->pRealFile = pReal;
    rc = sqlite3OsFileSize(pReal, &iSize);
    pWrapper->iSize = (int)iSize;
  }
  if( rc==SQLITE_OK ){
    pWrapper->nData = (4096 + pWrapper->iSize);
    pWrapper->zData = sqlite3_malloc(pWrapper->nData);
    if( pWrapper->zData ){
      memset(pWrapper->zData, 0, pWrapper->nData);
      rc = sqlite3OsRead(pReal, pWrapper->zData, pWrapper->iSize, 0); 
    }else{
      rc = SQLITE_NOMEM;
    }
  }
................................................................................
  int objc,
  Tcl_Obj *CONST objv[]
){
  int i;
  int iDelay;
  const char *zCrashFile;
  int nCrashFile;


  static sqlite3_vfs crashVfs = {
    1,                  /* iVersion */
    0,                  /* szOsFile */
    0,                  /* mxPathname */
    0,                  /* nRef */
    0,                  /* vfsMutex */

Changes to src/test8.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** 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 $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
    }
    for(i=2; i<nData; i++){
      if( apData[i]==0 ) continue;
      string_concat(&z, sqlite3_mprintf(
          "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1);
      zSep = ",";
    }
    string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 0);
  }

  /* If apData[0] is an integer and nData==1 then do a DELETE */
  else if( nData==1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){
    z = sqlite3_mprintf("DELETE FROM %Q WHERE rowid = ?1", pVtab->zTableName);
    bindArgZero = 1;
  }







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.53 2007/08/23 02:47:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
    }
    for(i=2; i<nData; i++){
      if( apData[i]==0 ) continue;
      string_concat(&z, sqlite3_mprintf(
          "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1);
      zSep = ",";
    }
    string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 1);
  }

  /* If apData[0] is an integer and nData==1 then do a DELETE */
  else if( nData==1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){
    z = sqlite3_mprintf("DELETE FROM %Q WHERE rowid = ?1", pVtab->zTableName);
    bindArgZero = 1;
  }

Changes to src/test_malloc.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30








31
32
33
34
35
36
37
..
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56







57
58
59
60
61
62
63
...
284
285
286
287
288
289
290
































291
292
293
294
295
296
297
...
302
303
304
305
306
307
308

309
310
311
312
313
314
315
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** 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 $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

/*
** Transform pointers to text and back again
*/
static void pointerToText(void *p, char *z){
  static const char zHex[] = "0123456789abcdef";
  int i, k;

  sqlite3_uint64 n = (sqlite3_uint64)p;








  for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){
    z[k] = zHex[n&0xf];
    n >>= 4;
  }
  z[sizeof(p)*2] = 0;
}
static int hexToInt(int h){
................................................................................
  }else{
    return -1;
  }
}
static int textToPointer(const char *z, void **pp){
  sqlite3_uint64 n = 0;
  int i;

  for(i=0; i<sizeof(void*)*2 && z[0]; i++){
    int v;
    v = hexToInt(*z++);
    if( v<0 ) return TCL_ERROR;
    n = n*16 + v;
  }
  if( *z!=0 ) return TCL_ERROR;
  *pp = (void*)n;







  return TCL_OK;
}

/*
** Usage:    sqlite3_malloc  NBYTES
**
** Raw test interface for sqlite3_malloc().
................................................................................
  Tcl_Obj *CONST objv[]
){
  extern int sqlite3_memdebug_pending(void);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_pending()));
  return TCL_OK;
}


































/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_malloc_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
................................................................................
     { "sqlite3_free",               test_free                     },
     { "sqlite3_memory_used",        test_memory_used              },
     { "sqlite3_memory_highwater",   test_memory_highwater         },
     { "sqlite3_memdebug_backtrace", test_memdebug_backtrace       },
     { "sqlite3_memdebug_dump",      test_memdebug_dump            },
     { "sqlite3_memdebug_fail",      test_memdebug_fail            },
     { "sqlite3_memdebug_pending",   test_memdebug_pending         },

  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  }
  return TCL_OK;
}







|













>
|
>
>
>
>
>
>
>
>







 







>







|
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.4 2007/08/23 02:47:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

/*
** Transform pointers to text and back again
*/
static void pointerToText(void *p, char *z){
  static const char zHex[] = "0123456789abcdef";
  int i, k;
  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;
  }
  z[sizeof(p)*2] = 0;
}
static int hexToInt(int h){
................................................................................
  }else{
    return -1;
  }
}
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++);
    if( v<0 ) return TCL_ERROR;
    n = n*16 + v;
  }
  if( *z!=0 ) return TCL_ERROR;
  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;
}

/*
** Usage:    sqlite3_malloc  NBYTES
**
** Raw test interface for sqlite3_malloc().
................................................................................
  Tcl_Obj *CONST objv[]
){
  extern int sqlite3_memdebug_pending(void);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_pending()));
  return TCL_OK;
}


/*
** 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){
  static struct {
     char *zName;
................................................................................
     { "sqlite3_free",               test_free                     },
     { "sqlite3_memory_used",        test_memory_used              },
     { "sqlite3_memory_highwater",   test_memory_highwater         },
     { "sqlite3_memdebug_backtrace", test_memdebug_backtrace       },
     { "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++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  }
  return TCL_OK;
}

Changes to src/vdbeaux.c.

1003
1004
1005
1006
1007
1008
1009


1010
1011
1012
1013
1014
1015
1016
1017


1018
1019
1020
1021
1022
1023
1024
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;


  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  sqlite3_free(p->aColName);
  n = nResColumn*COLNAME_N;
  p->nResColumn = nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    (pColName++)->flags = MEM_Null;


  }
}

/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**







>
>







|
>
>







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
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;
  p->nResColumn = nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    pColName->flags = MEM_Null;
    pColName->db = db;
    pColName++;
  }
}

/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**

Changes to src/vtab.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.52 2007/08/22 02:56:44 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

static int createModule(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
................................................................................
  Token *pName2,        /* Name of new table or NULL */
  Token *pModuleName    /* Name of the module for the virtual table */
){
  int iDb;              /* The database the table is being created in */
  Table *pTable;        /* The new virtual table */
  sqlite3 *db;          /* Database connection */

#if 0 /* FIX ME */
  if( sqlite3ThreadDataReadOnly()->useSharedData ){
    sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode");
    return;
  }
#endif

  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
  pTable = pParse->pNewTable;
  if( pTable==0 || pParse->nErr ) return;
  assert( 0==pTable->pIndex );

  db = pParse->db;







|







 







|
<



<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
163
164
165
166
167
168
169
170

171
172
173

174
175
176
177
178
179
180
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.53 2007/08/23 02:47:53 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

static int createModule(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
................................................................................
  Token *pName2,        /* Name of new table or NULL */
  Token *pModuleName    /* Name of the module for the virtual table */
){
  int iDb;              /* The database the table is being created in */
  Table *pTable;        /* The new virtual table */
  sqlite3 *db;          /* Database connection */

  if( pParse->db->flags & SQLITE_SharedCache ){

    sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode");
    return;
  }


  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
  pTable = pParse->pNewTable;
  if( pTable==0 || pParse->nErr ) return;
  assert( 0==pTable->pIndex );

  db = pParse->db;

Changes to test/all.test.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: all.test,v 1.45 2007/08/16 13:01:45 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {
  memleak_check
}

if {[file exists ./sqlite_test_count]} {
  set COUNT [exec cat ./sqlite_test_count]
} else {
  set COUNT 3
}







|





|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: all.test,v 1.46 2007/08/23 02:47:53 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {
  # no-op
}

if {[file exists ./sqlite_test_count]} {
  set COUNT [exec cat ./sqlite_test_count]
} else {
  set COUNT 3
}

Changes to test/malloc4.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis in this file is on sqlite3_column_XXX() APIs.
#
# $Id: malloc4.test,v 1.4 2007/08/22 22:04:37 drh Exp $

#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
#
# [193] When a memory allocation failure occurs during sqlite3_column_name(),
#       sqlite3_column_name16(), sqlite3_column_decltype(), or
#       sqlite3_column_decltype16() the function shall return NULL.
................................................................................
    #                 malloc() failures.
    #
    # Because the code that implements the _decltype() and _decltype16() APIs
    # is the same as the _name() and _name16() implementations, we don't worry
    # about explicitly testing them.
    #
    do_test ${testid}.2.1 {
      set mf1 [expr [sqlite3_memdebug_pending] <= 0]
      set ::name8  [sqlite3_column_name $::STMT 0]
      set mf2 [expr [sqlite3_memdebug_pending] <= 0]
      expr {$mf1 == $mf2 || $::name8 == ""}
    } {1}
    do_test ${testid}.2.2 {
      set mf1 [expr [sqlite3_memdebug_pending] <= 0]

      set ::name16 [sqlite3_column_name16 $::STMT 0]
      set ::name16 [encoding convertfrom unicode $::name16]
      set ::name16 [string range $::name16 0 end-1]
      set mf2 [expr [sqlite3_memdebug_pending] <= 0]

      expr {$mf1 == $mf2 || $::name16 == ""}
    } {1}
    do_test ${testid}.2.3 {
      set mf1 [expr [sqlite3_memdebug_pending] <= 0]
      set ::name8_2 [sqlite3_column_name $::STMT 0]
      set mf2 [expr [sqlite3_memdebug_pending] <= 0]
      expr {$mf1 == $mf2 || $::name8_2 == ""}
    } {1}
    set ::mallocFailed [expr [sqlite3_memdebug_pending] <= 0]
    do_test ${testid}.2.4 {
      expr {
        $::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed ||
        $::name8 == $::name8_2 && $::name16 == "" &&        $::mallocFailed ||
        $::name8 == $::name16 && $::name8_2 == "" &&        $::mallocFailed ||
        $::name8_2 == $::name16 && $::name8 == "" &&        $::mallocFailed
      }
................................................................................
    } {SQLITE_ROW}
    sqlite3_memdebug_fail $mf

    # Test for malloc() failures within _text() and _text16().
    #
    do_test ${testid}.4.1 {
      set ::text8 [sqlite3_column_text $::STMT 0]
      set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
      expr {$mf==0 || $::text8 == ""}
    } {1}
    do_test ${testid}.4.2 {
      set ::text16 [sqlite3_column_text16 $::STMT 0]
      set ::text16 [encoding convertfrom unicode $::text16]
      set ::text16 [string range $::text16 0 end-1]
      set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
      expr {$mf==0 || $::text16 == ""}
    } {1}
    do_test ${testid}.4.3 {
      set ::text8_2 [sqlite3_column_text $::STMT 0]
      set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
      expr {$mf==0 || $::text8_2 == "" || ($::text16 == "" && $::text8 != "")}
    } {1}

    # Test for malloc() failures within _int(), _int64() and _real(). The only
    # way this can occur is if the string has to be translated from UTF-16 to
    # UTF-8 before being converted to a numeric value.
    do_test ${testid}.4.4.1 {
................................................................................
      sqlite3_memdebug_fail -1
      sqlite3_column_text16 $::STMT 0
      sqlite3_memdebug_fail $mf
      sqlite3_column_double $::STMT 0
    } {0.0}

    set mallocFailedAfterStep [expr \
      [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed
    ]

    sqlite3_memdebug_fail -1
    # Test that if a malloc() failed the next call to sqlite3_step() returns
    # SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_DONE.
    #
    do_test ${testid}.5 {







|







 







|

|



|
>



|
>



|

|


|







 







|






|




|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis in this file is on sqlite3_column_XXX() APIs.
#
# $Id: malloc4.test,v 1.5 2007/08/23 02:47:53 drh Exp $

#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
#
# [193] When a memory allocation failure occurs during sqlite3_column_name(),
#       sqlite3_column_name16(), sqlite3_column_decltype(), or
#       sqlite3_column_decltype16() the function shall return NULL.
................................................................................
    #                 malloc() failures.
    #
    # Because the code that implements the _decltype() and _decltype16() APIs
    # is the same as the _name() and _name16() implementations, we don't worry
    # about explicitly testing them.
    #
    do_test ${testid}.2.1 {
      set mf1 [expr [sqlite3_memdebug_pending] < 0]
      set ::name8  [sqlite3_column_name $::STMT 0]
      set mf2 [expr [sqlite3_memdebug_pending] < 0]
      expr {$mf1 == $mf2 || $::name8 == ""}
    } {1}
    do_test ${testid}.2.2 {
      set mf1 [expr [sqlite3_memdebug_pending] < 0]
btree_breakpoint
      set ::name16 [sqlite3_column_name16 $::STMT 0]
      set ::name16 [encoding convertfrom unicode $::name16]
      set ::name16 [string range $::name16 0 end-1]
      set mf2 [expr [sqlite3_memdebug_pending] < 0]
puts [list $mf1 $mf2 $::name16]
      expr {$mf1 == $mf2 || $::name16 == ""}
    } {1}
    do_test ${testid}.2.3 {
      set mf1 [expr [sqlite3_memdebug_pending] < 0]
      set ::name8_2 [sqlite3_column_name $::STMT 0]
      set mf2 [expr [sqlite3_memdebug_pending] < 0]
      expr {$mf1 == $mf2 || $::name8_2 == ""}
    } {1}
    set ::mallocFailed [expr [sqlite3_memdebug_pending] < 0]
    do_test ${testid}.2.4 {
      expr {
        $::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed ||
        $::name8 == $::name8_2 && $::name16 == "" &&        $::mallocFailed ||
        $::name8 == $::name16 && $::name8_2 == "" &&        $::mallocFailed ||
        $::name8_2 == $::name16 && $::name8 == "" &&        $::mallocFailed
      }
................................................................................
    } {SQLITE_ROW}
    sqlite3_memdebug_fail $mf

    # Test for malloc() failures within _text() and _text16().
    #
    do_test ${testid}.4.1 {
      set ::text8 [sqlite3_column_text $::STMT 0]
      set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed]
      expr {$mf==0 || $::text8 == ""}
    } {1}
    do_test ${testid}.4.2 {
      set ::text16 [sqlite3_column_text16 $::STMT 0]
      set ::text16 [encoding convertfrom unicode $::text16]
      set ::text16 [string range $::text16 0 end-1]
      set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed]
      expr {$mf==0 || $::text16 == ""}
    } {1}
    do_test ${testid}.4.3 {
      set ::text8_2 [sqlite3_column_text $::STMT 0]
      set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed]
      expr {$mf==0 || $::text8_2 == "" || ($::text16 == "" && $::text8 != "")}
    } {1}

    # Test for malloc() failures within _int(), _int64() and _real(). The only
    # way this can occur is if the string has to be translated from UTF-16 to
    # UTF-8 before being converted to a numeric value.
    do_test ${testid}.4.4.1 {
................................................................................
      sqlite3_memdebug_fail -1
      sqlite3_column_text16 $::STMT 0
      sqlite3_memdebug_fail $mf
      sqlite3_column_double $::STMT 0
    } {0.0}

    set mallocFailedAfterStep [expr \
      [sqlite3_memdebug_pending] < 0 && !$::mallocFailed
    ]

    sqlite3_memdebug_fail -1
    # Test that if a malloc() failed the next call to sqlite3_step() returns
    # SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_DONE.
    #
    do_test ${testid}.5 {

Changes to test/quick.test.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
51
52
53
54
55
56
57

58
59
60
61
62
63
64
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.60 2007/08/16 13:01:45 drh Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
................................................................................
  fuzz.test
  fuzz_malloc.test
  in2.test
  loadext.test
  malloc.test
  malloc2.test
  malloc3.test

  memleak.test
  misc7.test
  misuse.test
  quick.test
  soak.test
  speed1.test
  speed2.test







|







 







>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.61 2007/08/23 02:47:54 drh Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
................................................................................
  fuzz.test
  fuzz_malloc.test
  in2.test
  loadext.test
  malloc.test
  malloc2.test
  malloc3.test
  malloc4.test
  memleak.test
  misc7.test
  misuse.test
  quick.test
  soak.test
  speed1.test
  speed2.test

Changes to test/shared2.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
120
121
122
123
124
125
126
127
128
129
130
131
132
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: shared2.test,v 1.4 2006/01/26 13:11:37 danielk1977 Exp $

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

ifcapable !shared_cache {
  finish_test
................................................................................
  set res
} {1 2 3 4 5}

db1 close
db2 close

do_test shared2-3.2 {
  sqlite3_thread_cleanup
  sqlite3_enable_shared_cache 1
} {0}

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test







|







 







<

|



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
120
121
122
123
124
125
126

127
128
129
130
131
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: shared2.test,v 1.5 2007/08/23 02:47:54 drh Exp $

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

ifcapable !shared_cache {
  finish_test
................................................................................
  set res
} {1 2 3 4 5}

db1 close
db2 close

do_test shared2-3.2 {

  sqlite3_enable_shared_cache 1
} {1}

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test

Changes to test/tester.tcl.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
58
59
60
61
62
63
64















65
66
67
68
69
70
71
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
...
219
220
221
222
223
224
225




226
227
228
229
230
231
232
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.86 2007/08/22 22:04:37 drh Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................
        set soft_limit $value
      }
      set argv [lreplace $argv $i $i]
    }
  }
}
sqlite3_soft_heap_limit $soft_limit
















# Use the pager codec if it is available
#
if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} {
  rename sqlite3 sqlite_orig
  proc sqlite3 {args} {
    if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} {
................................................................................
  set speedTest 0
}

# Invoke the do_test procedure to run a single test 
#
proc do_test {name cmd expected} {
  global argv nErr nTest skip_test maxErr
  set ::sqlite_malloc_id $name
  if {$skip_test} {
    set skip_test 0
    return
  }
  if {[llength $argv]==0} { 
    set go 1
  } else {
................................................................................
  set total_time 0
}
proc speed_trial_summary {name} {
  global total_time
  puts [format {%-21.21s %12d uS TOTAL} $name $total_time]
}

# The procedure uses the special "sqlite_malloc_stat" command
# (which is only available if SQLite is compiled with -DSQLITE_DEBUG=1)
# to see how many malloc()s have not been free()ed.  The number
# of surplus malloc()s is stored in the global variable $::Leak.
# If the value in $::Leak grows, it may mean there is a memory leak
# in the library.
#
proc memleak_check {} {
  if {[info command sqlite_malloc_stat]!=""} {
    set r [sqlite_malloc_stat]
    set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
  }
}

# Run this routine last
#
proc finish_test {} {
  finalize_testing
}
proc finalize_testing {} {
  global nTest nErr sqlite_open_file_count
  if {$nErr==0} memleak_check

  catch {db close}
  catch {db2 close}
  catch {db3 close}

  sqlite3 db {}
  # sqlite3_clear_tsd_memdebug
................................................................................
  if {$sqlite_open_file_count} {
    puts "$sqlite_open_file_count files were left open"
    incr nErr
  }
  if {[sqlite3_memory_used]>0} {
    puts "Unfreed memory: [sqlite3_memory_used] bytes"
    incr nErr




  } else {
    puts "All memory allocations freed - no leaks"
  }
  puts "Maximum memory usage: [sqlite3_memory_highwater] bytes"
  foreach f [glob -nocomplain test.db-*-journal] {
    file delete -force $f
  }







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







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







<







 







>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
176
177
178
179
180
181
182














183
184
185
186
187
188
189

190
191
192
193
194
195
196
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.87 2007/08/23 02:47:54 drh Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................
        set soft_limit $value
      }
      set argv [lreplace $argv $i $i]
    }
  }
}
sqlite3_soft_heap_limit $soft_limit

# 
# Check the command-line arguments to set the memory debugger
# backtrace depth.
#
# See the sqlite3_memdebug_backtrace() function in mem2.c or
# test_malloc.c for additional information.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[regexp {^--backtrace=(\d+)$} [lindex $argv $i] all value]} {
    sqlite3_memdebug_backtrace $value
    set argv [lreplace $argv $i $i]
  }
}


# Use the pager codec if it is available
#
if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} {
  rename sqlite3 sqlite_orig
  proc sqlite3 {args} {
    if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} {
................................................................................
  set speedTest 0
}

# Invoke the do_test procedure to run a single test 
#
proc do_test {name cmd expected} {
  global argv nErr nTest skip_test maxErr
  sqlite3_memdebug_settitle $name
  if {$skip_test} {
    set skip_test 0
    return
  }
  if {[llength $argv]==0} { 
    set go 1
  } else {
................................................................................
  set total_time 0
}
proc speed_trial_summary {name} {
  global total_time
  puts [format {%-21.21s %12d uS TOTAL} $name $total_time]
}















# Run this routine last
#
proc finish_test {} {
  finalize_testing
}
proc finalize_testing {} {
  global nTest nErr sqlite_open_file_count


  catch {db close}
  catch {db2 close}
  catch {db3 close}

  sqlite3 db {}
  # sqlite3_clear_tsd_memdebug
................................................................................
  if {$sqlite_open_file_count} {
    puts "$sqlite_open_file_count files were left open"
    incr nErr
  }
  if {[sqlite3_memory_used]>0} {
    puts "Unfreed memory: [sqlite3_memory_used] bytes"
    incr nErr
    ifcapable memdebug {
      puts "Writing unfreed memory log to \"./memleak.txt\""
      sqlite3_memdebug_dump ./memleak.txt
    }
  } else {
    puts "All memory allocations freed - no leaks"
  }
  puts "Maximum memory usage: [sqlite3_memory_highwater] bytes"
  foreach f [glob -nocomplain test.db-*-journal] {
    file delete -force $f
  }