/ Check-in [56c8af14]
Login

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

Overview
Comment:Add a mode to the sqlite3_test_control() interface to register hooks called at the beginning and end of "benign malloc failure" blocks. This allows malloc() failure testing to be done using public APIs only. (CVS 5254)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 56c8af1452dfdc8da858a2411bd6f3663a8a9326
User & Date: danielk1977 2008-06-20 14:59:51
Context
2008-06-20
15:24
Change the SRT_Subroutine mode into SRT_Coroutine. Use co-routines in the INSERT processing logic. (CVS 5255) check-in: 6b9d92fc user: drh tags: trunk
14:59
Add a mode to the sqlite3_test_control() interface to register hooks called at the beginning and end of "benign malloc failure" blocks. This allows malloc() failure testing to be done using public APIs only. (CVS 5254) check-in: 56c8af14 user: danielk1977 tags: trunk
11:05
Move (almost all) malloc failure test logic from fault.c to test_malloc.c. (CVS 5253) check-in: 4ae21e34 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/bitvec.c.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
** Clear operations are exceedingly rare.  There are usually between
** 5 and 500 set operations per Bitvec object, though the number of sets can
** sometimes grow into tens of thousands or larger.  The size of the
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.5 2008/05/13 13:27:34 drh Exp $
*/
#include "sqliteInt.h"

#define BITVEC_SZ        512
/* Round the union size down to the nearest pointer boundary, since that's how 
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE     (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*))
................................................................................
    p->u.aBitmap[i/8] |= 1 << (i&7);
    return SQLITE_OK;
  }
  if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
    if( p->u.apSub[bin]==0 ){
      sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
      sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
    }
    return sqlite3BitvecSet(p->u.apSub[bin], i);
  }
  h = BITVEC_HASH(i);
  while( p->u.aHash[h] ){
    if( p->u.aHash[h]==i ) return SQLITE_OK;







|







 







|

|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
** Clear operations are exceedingly rare.  There are usually between
** 5 and 500 set operations per Bitvec object, though the number of sets can
** sometimes grow into tens of thousands or larger.  The size of the
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.6 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"

#define BITVEC_SZ        512
/* Round the union size down to the nearest pointer boundary, since that's how 
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE     (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*))
................................................................................
    p->u.aBitmap[i/8] |= 1 << (i&7);
    return SQLITE_OK;
  }
  if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
    if( p->u.apSub[bin]==0 ){
      sqlite3BeginBenignMalloc();
      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
      sqlite3EndBenignMalloc();
      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
    }
    return sqlite3BitvecSet(p->u.apSub[bin], i);
  }
  h = BITVEC_HASH(i);
  while( p->u.aHash[h] ){
    if( p->u.aHash[h]==i ) return SQLITE_OK;

Changes to src/fault.c.

6
7
8
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
47
48
49


50
51
52

53
54


55
56
57
58
**
**    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 to support the concept of "benign" 
** malloc failures. 


**
** $Id: fault.c,v 1.8 2008/06/20 11:05:38 danielk1977 Exp $







*/

#include "sqliteInt.h"

#ifndef SQLITE_OMIT_BUILTIN_TEST

/*
** If zero, malloc() failures are non-benign. If non-zero, benign.
*/
static int memfault_is_benign = 0;




/*
** Return true if a malloc failures are currently considered to be
** benign. A benign fault does not affect the operation of sqlite.
** By constrast a non-benign fault causes sqlite to fail the current 
** operation and return SQLITE_NOMEM to the user.

*/
int sqlite3FaultIsBenign(void){
  return memfault_is_benign;





}

/* 
** After this routine causes subsequent malloc faults to be either 
** benign or hard (not benign), according to the "enable" parameter.
**
** Most faults are hard.  In other words, most faults cause
** an error to be propagated back up to the application interface.
** However, sometimes a fault is easily recoverable.  For example,
** if a malloc fails while resizing a hash table, this is completely
** recoverable simply by not carrying out the resize.  The hash table
** will continue to function normally.  So a malloc failure during
** a hash table resize is a benign fault.  
*/


void sqlite3FaultBeginBenign(int id){
  memfault_is_benign++;
}

void sqlite3FaultEndBenign(int id){
  memfault_is_benign--;


}

#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */








>
>
>
>

|
>
>

<
>
>
>
>
>
>
>







|

|
>
>
>


<
<
<
|
>

<
|
>
>
>
>
>


|
<
<
<
<
<
|
|
|
<
<

>
>
|
<
|
>
|
|
>
>




6
7
8
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

47
48
49
50
51
52
53
54
55





56
57
58


59
60
61
62

63
64
65
66
67
68
69
70
71
72
**
**    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: fault.c,v 1.9 2008/06/20 14:59:51 danielk1977 Exp $
*/

/*
** This file contains code to support the concept of "benign" 
** malloc failures (when the xMalloc() or xRealloc() method of the
** sqlite3_mem_methods structure fails to allocate a block of memory
** and returns 0). 
**

** Most malloc failures are non-benign. After they occur, SQLite
** abandons the current operation and returns an error code (usually
** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
** fatal. For example, if a malloc fails while resizing a hash table, this 
** is completely recoverable simply by not carrying out the resize. The 
** hash table will continue to function normally.  So a malloc failure 
** during a hash table resize is a benign fault.
*/

#include "sqliteInt.h"

#ifndef SQLITE_OMIT_BUILTIN_TEST

/*
** Global variables.
*/
static struct BenignMallocHooks {
  void (*xBenignBegin)(void);
  void (*xBenignEnd)(void);
} hooks;

/*



** Register hooks to call when sqlite3BeginBenignMalloc() and
** sqlite3EndBenignMalloc() are called, respectively.
*/

void sqlite3BenignMallocHooks(
  void (*xBenignBegin)(void),
  void (*xBenignEnd)(void)
){
  hooks.xBenignBegin = xBenignBegin;
  hooks.xBenignEnd = xBenignEnd;
}

/*





** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
** indicates that subsequent malloc failures are non-benign.


*/
void sqlite3BeginBenignMalloc(void){
  if( hooks.xBenignBegin ){
    hooks.xBenignBegin();

  }
}
void sqlite3EndBenignMalloc(void){
  if( hooks.xBenignEnd ){
    hooks.xBenignEnd();
  }
}

#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */

Changes to src/hash.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.29 2008/06/15 02:51:47 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
................................................................................
#endif

  /* There is a call to sqlite3_malloc() inside rehash(). If there is
  ** already an allocation at pH->ht, then if this malloc() fails it
  ** is benign (since failing to resize a hash table is a performance
  ** hit only, not a fatal error).
  */
  if( pH->htsize>0 ) sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
  if( pH->htsize>0 ) sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);

  if( new_ht==0 ) return;
  sqlite3_free(pH->ht);
  pH->ht = new_ht;
  pH->htsize = new_size;
  xHash = hashFunction(pH->keyClass);
  for(elem=pH->first, pH->first=0; elem; elem = next_elem){







|







 







|

|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.30 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
................................................................................
#endif

  /* There is a call to sqlite3_malloc() inside rehash(). If there is
  ** already an allocation at pH->ht, then if this malloc() fails it
  ** is benign (since failing to resize a hash table is a performance
  ** hit only, not a fatal error).
  */
  if( pH->htsize>0 ) sqlite3BeginBenignMalloc();
  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
  if( pH->htsize>0 ) sqlite3EndBenignMalloc();

  if( new_ht==0 ) return;
  sqlite3_free(pH->ht);
  pH->ht = new_ht;
  pH->htsize = new_size;
  xHash = hashFunction(pH->keyClass);
  for(elem=pH->first, pH->first=0; elem; elem = next_elem){

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
....
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
....
1868
1869
1870
1871
1872
1873
1874















1875
1876
1877
1878
1879
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.454 2008/06/20 11:05:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
................................................................................
/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  int inTrans = 0;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  sqlite3VtabRollback(db);
  sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);

  if( db->flags&SQLITE_InternChanges ){
    sqlite3ExpirePreparedStatements(db);
    sqlite3ResetInternalSchema(db, 0);
  }

  /* If one has been configured, invoke the rollback-hook callback */
................................................................................
*/
int sqlite3_test_control(int op, ...){
  int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
  va_list ap;
  va_start(ap, op);
  switch( op ){
#if 0
    /*
    ** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat)
    **
    ** Configure a fault injector.  The specific fault injector is
    ** identified by the fault_id argument.  (ex: SQLITE_FAULTINJECTOR_MALLOC)
    ** The fault will occur after a delay of nDelay calls.  The fault
    ** will repeat nRepeat times.
    */
    case SQLITE_TESTCTRL_FAULT_CONFIG: {
      int id = va_arg(ap, int);
      int nDelay = va_arg(ap, int);
      int nRepeat = va_arg(ap, int);
      sqlite3FaultConfig(id, nDelay, nRepeat);
      break;
    }

    /*
    ** sqlite3_test_control(FAULT_FAILURES, fault_id)
    **
    ** Return the number of faults (both hard and benign faults) that have
    ** occurred since the injector identified by fault_id) was last configured.
    */
    case SQLITE_TESTCTRL_FAULT_FAILURES: {
      int id = va_arg(ap, int);
      rc = sqlite3FaultFailures(id);
      break;
    }

    /*
    ** sqlite3_test_control(FAULT_BENIGN_FAILURES, fault_id)
    **
    ** Return the number of benign faults that have occurred since the
    ** injector identified by fault_id was last configured.
    */
    case SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES: {
      int id = va_arg(ap, int);
      rc = sqlite3FaultBenignFailures(id);
      break;
    }

    /*
    ** sqlite3_test_control(FAULT_PENDING, fault_id)
    **
    ** Return the number of successes that will occur before the next
    ** scheduled failure on fault injector fault_id.
    ** If no failures are scheduled, return -1.
    */
    case SQLITE_TESTCTRL_FAULT_PENDING: {
      int id = va_arg(ap, int);
      rc = sqlite3FaultPending(id);
      break;
    }

    /*
    ** sqlite3_test_control(FAULT_INSTALL, isInstall)
    **
    ** If the argument is non-zero, install the fault-simulation malloc layer
    ** as a wrapper around the currently installed implementation.
    */
    case SQLITE_TESTCTRL_FAULT_INSTALL: {
      int isInstall = va_arg(ap, int);
      rc = sqlite3FaultsimInstall(isInstall);
      break;
    }
#endif

    /*
    ** Save the current state of the PRNG.
    */
    case SQLITE_TESTCTRL_PRNG_SAVE: {
      sqlite3PrngSaveState();
      break;
................................................................................
    */
    case SQLITE_TESTCTRL_BITVEC_TEST: {
      int sz = va_arg(ap, int);
      int *aProg = va_arg(ap, int*);
      rc = sqlite3BitvecBuiltinTest(sz, aProg);
      break;
    }















  }
  va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
  return rc;
}







|







 







|










|







 







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







 







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





10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
....
1759
1760
1761
1762
1763
1764
1765


































































1766
1767
1768
1769
1770
1771
1772
....
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.455 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
................................................................................
/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  int inTrans = 0;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3BeginBenignMalloc();
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  sqlite3VtabRollback(db);
  sqlite3EndBenignMalloc();

  if( db->flags&SQLITE_InternChanges ){
    sqlite3ExpirePreparedStatements(db);
    sqlite3ResetInternalSchema(db, 0);
  }

  /* If one has been configured, invoke the rollback-hook callback */
................................................................................
*/
int sqlite3_test_control(int op, ...){
  int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
  va_list ap;
  va_start(ap, op);
  switch( op ){



































































    /*
    ** Save the current state of the PRNG.
    */
    case SQLITE_TESTCTRL_PRNG_SAVE: {
      sqlite3PrngSaveState();
      break;
................................................................................
    */
    case SQLITE_TESTCTRL_BITVEC_TEST: {
      int sz = va_arg(ap, int);
      int *aProg = va_arg(ap, int*);
      rc = sqlite3BitvecBuiltinTest(sz, aProg);
      break;
    }

    /*
    **  sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
    **
    ** Register hooks to call to indicate which malloc() failures 
    ** are benign.
    */
    case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: {
      void (*xBenignBegin)(void);
      void (*xBenignEnd)(void);
      xBenignBegin = va_arg(ap, void(*)(void));
      xBenignEnd = va_arg(ap, void(*)(void));
      sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd);
      break;
    }
  }
  va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
  return rc;
}

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
....
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
....
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.459 2008/06/18 17:09:10 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
#ifdef SQLITE_MALLOC_SOFT_LIMIT
  if( N*sizeof(aHash[0])>SQLITE_MALLOC_SOFT_LIMIT ){
    N = SQLITE_MALLOC_SOFT_LIMIT/sizeof(aHash[0]);
  }
  if( N==pPager->nHash ) return;
#endif
  pagerLeave(pPager);
  if( pPager->aHash!=0 ) sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
  aHash = sqlite3MallocZero( sizeof(aHash[0])*N );
  if( pPager->aHash!=0 ) sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
  pagerEnter(pPager);
  if( aHash==0 ){
    /* Failure to rehash is not an error.  It is only a performance hit. */
    return;
  }
  sqlite3_free(pPager->aHash);
  pPager->nHash = N;
................................................................................
** Execute a rollback if a transaction is active and unlock the 
** database file. If the pager has already entered the error state, 
** do not attempt the rollback.
*/
static void pagerUnlockAndRollback(Pager *p){
  /* assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); */
  if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
    sqlite3FaultBeginBenign(-1);
    sqlite3PagerRollback(p);
    sqlite3FaultEndBenign(-1);
  }
  pager_unlock(p);
#if 0
  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );
#endif
}
................................................................................
      pPager->pNext->pPrev = pPager->pPrev;
    }
    sqlite3_mutex_leave(mutex);
  }
#endif

  disable_simulated_io_errors();
  sqlite3FaultBeginBenign(-1);
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
  enable_simulated_io_errors();
  sqlite3FaultEndBenign(-1);
  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
  IOTRACE(("CLOSE %p\n", pPager))
  if( pPager->journalOpen ){
    sqlite3OsClose(pPager->jfd);
  }
  sqlite3BitvecDestroy(pPager->pInJournal);
  if( pPager->stmtOpen ){







|







 







|

|







 







|

|







 







|





|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
....
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
....
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.460 2008/06/20 14:59:51 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
#ifdef SQLITE_MALLOC_SOFT_LIMIT
  if( N*sizeof(aHash[0])>SQLITE_MALLOC_SOFT_LIMIT ){
    N = SQLITE_MALLOC_SOFT_LIMIT/sizeof(aHash[0]);
  }
  if( N==pPager->nHash ) return;
#endif
  pagerLeave(pPager);
  if( pPager->aHash!=0 ) sqlite3BeginBenignMalloc();
  aHash = sqlite3MallocZero( sizeof(aHash[0])*N );
  if( pPager->aHash!=0 ) sqlite3EndBenignMalloc();
  pagerEnter(pPager);
  if( aHash==0 ){
    /* Failure to rehash is not an error.  It is only a performance hit. */
    return;
  }
  sqlite3_free(pPager->aHash);
  pPager->nHash = N;
................................................................................
** Execute a rollback if a transaction is active and unlock the 
** database file. If the pager has already entered the error state, 
** do not attempt the rollback.
*/
static void pagerUnlockAndRollback(Pager *p){
  /* assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); */
  if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
    sqlite3BeginBenignMalloc();
    sqlite3PagerRollback(p);
    sqlite3EndBenignMalloc();
  }
  pager_unlock(p);
#if 0
  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );
#endif
}
................................................................................
      pPager->pNext->pPrev = pPager->pPrev;
    }
    sqlite3_mutex_leave(mutex);
  }
#endif

  disable_simulated_io_errors();
  sqlite3BeginBenignMalloc();
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
  enable_simulated_io_errors();
  sqlite3EndBenignMalloc();
  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
  IOTRACE(("CLOSE %p\n", pPager))
  if( pPager->journalOpen ){
    sqlite3OsClose(pPager->jfd);
  }
  sqlite3BitvecDestroy(pPager->pInJournal);
  if( pPager->stmtOpen ){

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063

6064
6065
6066
6067
6068
6069
6070
** 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.341 2008/06/19 18:17:50 danielk1977 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++.
................................................................................
** as the first argument to [sqlite3_test_control()].
**
** These parameters and their meanings are subject to change
** without notice.  These values are for testing purposes only.
** Applications should not use any of these parameters or the
** [sqlite3_test_control()] interface.
*/
#define SQLITE_TESTCTRL_FAULT_CONFIG             1
#define SQLITE_TESTCTRL_FAULT_FAILURES           2
#define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES    3
#define SQLITE_TESTCTRL_FAULT_PENDING            4
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8
#define SQLITE_TESTCTRL_FAULT_INSTALL            9


/*
** CAPI3REF: SQLite Runtime Status {F17200}
**
** This interface is used to retrieve run-time status information
** about the preformance of SQLite, and optionally to reset various
** highwater marks.  The first argument is an integer code for







|







 







<
<
<
<





>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
6048
6049
6050
6051
6052
6053
6054




6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
** 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.342 2008/06/20 14:59:51 danielk1977 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++.
................................................................................
** as the first argument to [sqlite3_test_control()].
**
** These parameters and their meanings are subject to change
** without notice.  These values are for testing purposes only.
** Applications should not use any of these parameters or the
** [sqlite3_test_control()] interface.
*/




#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8
#define SQLITE_TESTCTRL_FAULT_INSTALL            9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10

/*
** CAPI3REF: SQLite Runtime Status {F17200}
**
** This interface is used to retrieve run-time status information
** about the preformance of SQLite, and optionally to reset various
** highwater marks.  The first argument is an integer code for

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
**    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.719 2008/06/20 11:05:38 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
................................................................................

/*
** The interface to the code in fault.c used for identifying "benign"
** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
** is not defined.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
  void sqlite3FaultBeginBenign(int);
  void sqlite3FaultEndBenign(int);
  int sqlite3FaultIsBenign(void);
#else
  #define sqlite3FaultBeginBenign()
  #define sqlite3FaultEndBenign()
#endif

#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX           3
int sqlite3FindInIndex(Parse *, Expr *, int);







|







 







|
|
<

|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
2204
2205
2206
2207
2208
2209
2210
2211
2212

2213
2214
2215
2216
2217
2218
2219
2220
2221
**    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.720 2008/06/20 14:59:51 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
................................................................................

/*
** The interface to the code in fault.c used for identifying "benign"
** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
** is not defined.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
  void sqlite3BeginBenignMalloc(void);
  void sqlite3EndBenignMalloc(void);

#else
  #define sqlite3BeginBenignMalloc()
  #define sqlite3FaultEndBenign()
#endif

#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX           3
int sqlite3FindInIndex(Parse *, Expr *, int);

Changes to src/test8.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
**    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.65 2008/06/16 14:19:58 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  echo_vtab *pVtab = (echo_vtab*)tab;
  int rc;

  /* Ticket #3083 - Only call xCommit if we have previously started
  ** a transaction */
  assert( pVtab->inTransaction );

  sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
  rc = echoTransactionCall(tab, "xCommit");
  sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
  pVtab->inTransaction = 0;
  return rc;
}
static int echoRollback(sqlite3_vtab *tab){
  int rc;
  echo_vtab *pVtab = (echo_vtab*)tab;








|







 







|

|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
**    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.66 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  echo_vtab *pVtab = (echo_vtab*)tab;
  int rc;

  /* Ticket #3083 - Only call xCommit if we have previously started
  ** a transaction */
  assert( pVtab->inTransaction );

  sqlite3BeginBenignMalloc();
  rc = echoTransactionCall(tab, "xCommit");
  sqlite3EndBenignMalloc();
  pVtab->inTransaction = 0;
  return rc;
}
static int echoRollback(sqlite3_vtab *tab){
  int rc;
  echo_vtab *pVtab = (echo_vtab*)tab;

Changes to src/test_malloc.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
28
29
30
31
32
33
34

35
36
37
38
39
40
41
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
157
158
159
160
161
162
163








164
165
166
167
168
169
170
...
181
182
183
184
185
186
187

188
189
190
191








192
193
194
195
196
197
198
....
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
**    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.27 2008/06/20 11:05:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

................................................................................
static struct MemFault {
  int iCountdown;         /* Number of pending successes before a failure */
  int nRepeat;            /* Number of times to repeat the failure */
  int nBenign;            /* Number of benign failures seen since last config */
  int nFail;              /* Number of failures seen since last config */
  u8 enable;              /* True if enabled */
  int isInstalled;        /* True if the fault simulation layer is installed */

  sqlite3_mem_methods m;  /* 'Real' malloc implementation */
} memfault;

/*
** This routine exists as a place to set a breakpoint that will
** fire on any simulated malloc() failure.
*/
................................................................................
  }
  if( memfault.iCountdown>0 ){
    memfault.iCountdown--;
    return 0;
  }
  sqlite3Fault();
  memfault.nFail++;
  if( sqlite3FaultIsBenign()>0 ){
    memfault.nBenign++;
  }
  memfault.nRepeat--;
  if( memfault.nRepeat<=0 ){
    memfault.enable = 0;
  }
  return 1;  
................................................................................
  if( memfault.enable ){
    return memfault.iCountdown;
  }else{
    return -1;
  }
}









/*
** Add or remove the fault-simulation layer using sqlite3_config(). If
** the argument is non-zero, the 
*/
static int faultsimInstall(int install){
  static struct sqlite3_mem_methods m = {
    faultsimMalloc,                   /* xMalloc */
................................................................................
  install = (install ? 1 : 0);
  assert(memfault.isInstalled==1 || memfault.isInstalled==0);

  if( install==memfault.isInstalled ){
    return SQLITE_ERROR;
  }


  rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
  assert(memfault.m.xMalloc);
  if( rc==SQLITE_OK ){
    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);








  }

  if( rc==SQLITE_OK ){
    memfault.isInstalled = 1;
  }
  return rc;
}
................................................................................
     { "sqlite3_memdebug_pending",   test_memdebug_pending         },
     { "sqlite3_memdebug_settitle",  test_memdebug_settitle        },
     { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count },
     { "sqlite3_memdebug_log",       test_memdebug_log             },
     { "sqlite3_config_scratch",     test_config_scratch           },
     { "sqlite3_config_pagecache",   test_config_pagecache         },
     { "sqlite3_status",             test_status                   },

     { "install_malloc_faultsim",    test_install_malloc_faultsim  },
  };
  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;
}
#endif







|







 







>







 







|







 







>
>
>
>
>
>
>
>







 







>
|
|
|
|
>
>
>
>
>
>
>
>







 







<









9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
....
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
**    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.28 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

................................................................................
static struct MemFault {
  int iCountdown;         /* Number of pending successes before a failure */
  int nRepeat;            /* Number of times to repeat the failure */
  int nBenign;            /* Number of benign failures seen since last config */
  int nFail;              /* Number of failures seen since last config */
  u8 enable;              /* True if enabled */
  int isInstalled;        /* True if the fault simulation layer is installed */
  int isBenignMode;       /* True if malloc failures are considered benign */
  sqlite3_mem_methods m;  /* 'Real' malloc implementation */
} memfault;

/*
** This routine exists as a place to set a breakpoint that will
** fire on any simulated malloc() failure.
*/
................................................................................
  }
  if( memfault.iCountdown>0 ){
    memfault.iCountdown--;
    return 0;
  }
  sqlite3Fault();
  memfault.nFail++;
  if( memfault.isBenignMode>0 ){
    memfault.nBenign++;
  }
  memfault.nRepeat--;
  if( memfault.nRepeat<=0 ){
    memfault.enable = 0;
  }
  return 1;  
................................................................................
  if( memfault.enable ){
    return memfault.iCountdown;
  }else{
    return -1;
  }
}


static void faultsimBeginBenign(void){
  memfault.isBenignMode++;
}
static void faultsimEndBenign(void){
  memfault.isBenignMode--;
}

/*
** Add or remove the fault-simulation layer using sqlite3_config(). If
** the argument is non-zero, the 
*/
static int faultsimInstall(int install){
  static struct sqlite3_mem_methods m = {
    faultsimMalloc,                   /* xMalloc */
................................................................................
  install = (install ? 1 : 0);
  assert(memfault.isInstalled==1 || memfault.isInstalled==0);

  if( install==memfault.isInstalled ){
    return SQLITE_ERROR;
  }

  if( install ){
    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
    assert(memfault.m.xMalloc);
    if( rc==SQLITE_OK ){
      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
    }
    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 
        faultsimBeginBenign, faultsimEndBenign
    );
  }else{
    assert(memfault.m.xMalloc);
    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
  }

  if( rc==SQLITE_OK ){
    memfault.isInstalled = 1;
  }
  return rc;
}
................................................................................
     { "sqlite3_memdebug_pending",   test_memdebug_pending         },
     { "sqlite3_memdebug_settitle",  test_memdebug_settitle        },
     { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count },
     { "sqlite3_memdebug_log",       test_memdebug_log             },
     { "sqlite3_config_scratch",     test_config_scratch           },
     { "sqlite3_config_pagecache",   test_config_pagecache         },
     { "sqlite3_status",             test_status                   },

     { "install_malloc_faultsim",    test_install_malloc_faultsim  },
  };
  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;
}
#endif

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.749 2008/06/15 02:51:48 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
  sqlite3FaultBeginBenign(-1);
  if( p->pc==0 
   && ((p->db->flags & SQLITE_VdbeListing) || fileExists(db, "vdbe_explain"))
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( fileExists(db, "vdbe_trace") ){
    p->trace = stdout;
  }
  sqlite3FaultEndBenign(-1);
#endif
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = sqlite3Hwtime();
................................................................................
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
    if( p->trace==0 && pc==0 ){
      sqlite3FaultBeginBenign(-1);
      if( fileExists(db, "vdbe_sqltrace") ){
        sqlite3VdbePrintSql(p);
      }
      sqlite3FaultEndBenign(-1);
    }
#endif
      

    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */







|







 







|













|







 







|



|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.750 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
  sqlite3BeginBenignMalloc();
  if( p->pc==0 
   && ((p->db->flags & SQLITE_VdbeListing) || fileExists(db, "vdbe_explain"))
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( fileExists(db, "vdbe_trace") ){
    p->trace = stdout;
  }
  sqlite3EndBenignMalloc();
#endif
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = sqlite3Hwtime();
................................................................................
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
    if( p->trace==0 && pc==0 ){
      sqlite3BeginBenignMalloc();
      if( fileExists(db, "vdbe_sqltrace") ){
        sqlite3VdbePrintSql(p);
      }
      sqlite3EndBenignMalloc();
    }
#endif
      

    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */

Changes to src/vdbeaux.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.388 2008/06/18 15:34:10 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"



................................................................................
    ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
    ** deleting or truncating journals. If something goes wrong while
    ** this is happening we don't really care. The integrity of the
    ** transaction is already guaranteed, but some stray 'cold' journals
    ** may be lying around. Returning an error code won't help matters.
    */
    disable_simulated_io_errors();
    sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        sqlite3BtreeCommitPhaseTwo(pBt);
      }
    }
    sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
    enable_simulated_io_errors();

    sqlite3VtabCommit(db);
  }
#endif

  return rc;







|







 







|






|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.389 2008/06/20 14:59:51 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"



................................................................................
    ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
    ** deleting or truncating journals. If something goes wrong while
    ** this is happening we don't really care. The integrity of the
    ** transaction is already guaranteed, but some stray 'cold' journals
    ** may be lying around. Returning an error code won't help matters.
    */
    disable_simulated_io_errors();
    sqlite3BeginBenignMalloc();
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        sqlite3BtreeCommitPhaseTwo(pBt);
      }
    }
    sqlite3EndBenignMalloc();
    enable_simulated_io_errors();

    sqlite3VtabCommit(db);
  }
#endif

  return rc;