/ Check-in [3cb704c4]
Login

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

Overview
Comment:Allow the xAccess method in the VFS to return -1 to signal an I/O error, and in particular an SQLITE_IOERR_NOMEM. (CVS 4925)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:3cb704c4c439425781644b1b653b7e50f02fd91e
User & Date: drh 2008-03-27 22:42:52
Context
2008-03-28
07:42
If memory is leaked when running a test script with the --malloctrace option, write out a file called leaks.sql in the same format as mallocs.sql containing th e leaked applications. The same tools can then be used to examine the stack traces associated with leaked allocations. (CVS 4926) check-in: f1b97ed9 user: danielk1977 tags: trunk
2008-03-27
22:42
Allow the xAccess method in the VFS to return -1 to signal an I/O error, and in particular an SQLITE_IOERR_NOMEM. (CVS 4925) check-in: 3cb704c4 user: drh tags: trunk
17:59
Allow creation of ephemeral pseudo-tables - pseudo-tables that copy a pointer to a row when inserted instead of copying the row data. (CVS 4924) check-in: 1a58a870 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/fault.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
...
101
102
103
104
105
106
107





108
109

110
111
112
113
114
115
116
*/
static struct FaultInjector {
  int iCountdown;   /* Number of pending successes before we hit 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 */
  u8 benign;        /* Ture if next failure will be benign */
} aFault[SQLITE_FAULTINJECTOR_COUNT];

/*
** This routine configures and enables a fault injector.  After
** calling this routine, aFaultStep() will return false (zero)
** nDelay times, then it will return true nRepeat times,
** then it will again begin returning false.
................................................................................
** 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 sqlite3FaultBenign(int id, int enable){





  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  aFault[id].benign = enable;

}

/*
** This routine exists as a place to set a breakpoint that will
** fire on any simulated fault.
*/
static void sqlite3Fault(void){







|







 







>
>
>
>
>
|
|
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
*/
static struct FaultInjector {
  int iCountdown;   /* Number of pending successes before we hit 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 */
  u8 benign;        /* True if next failure will be benign */
} aFault[SQLITE_FAULTINJECTOR_COUNT];

/*
** This routine configures and enables a fault injector.  After
** calling this routine, aFaultStep() will return false (zero)
** nDelay times, then it will return true nRepeat times,
** then it will again begin returning false.
................................................................................
** 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 sqlite3FaultBenign(int id, int enable){
  if( id<0 ){
    for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
      aFault[id].benign = enable;
    }
  }else{
    assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
    aFault[id].benign = enable;
  }
}

/*
** This routine exists as a place to set a breakpoint that will
** fire on any simulated fault.
*/
static void sqlite3Fault(void){

Changes to src/os.c.

111
112
113
114
115
116
117






118
119
120
121
122
123
124
125
  DO_OS_MALLOC_TEST;
  return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
}
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return pVfs->xDelete(pVfs, zPath, dirSync);
}
int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){






  int rc = pVfs->xAccess(pVfs, zPath, flags);
  assert( rc==0 || rc==1 );
  return rc;
}
int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
  return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
}
int sqlite3OsFullPathname(







>
>
>
>
>
>
|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  DO_OS_MALLOC_TEST;
  return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
}
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return pVfs->xDelete(pVfs, zPath, dirSync);
}
int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
  int rc;
#ifdef SQLITE_TEST
  void *pTstAlloc = sqlite3_malloc(10);
  if (!pTstAlloc) return -1;
  sqlite3_free(pTstAlloc);
#endif
  rc = pVfs->xAccess(pVfs, zPath, flags);
  assert( rc==0 || rc==1 );
  return rc;
}
int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
  return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
}
int sqlite3OsFullPathname(

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1598
1599
1600
1601
1602
1603
1604
1605





1606
1607
1608
1609
1610
1611
1612
....
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
....
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061


3062
3063
3064

3065
3066
3067

3068
3069
3070
3071
3072
3073
3074
3075
....
3361
3362
3363
3364
3365
3366
3367
3368




3369
3370
3371
3372
3373
3374
3375
....
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
** 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.420 2008/03/20 11:04:21 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
    }
    zMasterPtr = &zMasterJournal[nMasterJournal];
    rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
    if( rc!=SQLITE_OK ) goto delmaster_out;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      if( sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS) ){





        /* One of the journals pointed to by the master journal exists.
        ** Open it and check if it points at the master journal. If
        ** so, return without deleting the master journal file.
        */
        int c;
        int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
        rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
................................................................................
  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  */
  zMaster = pPager->pTmpSpace;
  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
  assert( rc!=SQLITE_DONE );
  if( rc!=SQLITE_OK 
   || (zMaster[0] && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) 
  ){
    zMaster = 0;
    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
    goto end_playback;
  }
  pPager->journalOff = 0;
  zMaster = 0;

  /* This loop terminates either when the readJournalHdr() call returns
  ** SQLITE_DONE or an IO error occurs. */
................................................................................
  assert( n1==n2 );
#endif

  return pPager->pDirty;
}

/*
** Return TRUE if there is a hot journal on the given pager.
** A hot journal is one that needs to be played back.
**
** If the current size of the database file is 0 but a journal file
** exists, that is probably an old journal left over from a prior
** database with the same name.  Just delete the journal.


*/
static int hasHotJournal(Pager *pPager){
  sqlite3_vfs *pVfs = pPager->pVfs;

  if( !pPager->useJournal ) return 0;
  if( !pPager->fd->pMethods ) return 0;
  if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){

    return 0;
  }
  if( sqlite3OsCheckReservedLock(pPager->fd) ){
    return 0;
  }
  if( sqlite3PagerPagecount(pPager)==0 ){
    sqlite3OsDelete(pVfs, pPager->zJournal, 0);
    return 0;
................................................................................
        }
        assert( pPager->state>=SHARED_LOCK );
      }
  
      /* If a journal file exists, and there is no RESERVED lock on the
      ** database file, then it either needs to be played back or deleted.
      */
      if( hasHotJournal(pPager) || isHot ){




        /* Get an EXCLUSIVE lock on the database file. At this point it is
        ** important that a RESERVED lock is not obtained on the way to the
        ** EXCLUSIVE lock. If it were, another process might open the
        ** database file, detect the RESERVED lock, and conclude that the
        ** database is safe to read while this process is still rolling it 
        ** back.
        ** 
................................................................................
        ** exclusive-access mode the file descriptor will be kept open and
        ** possibly used for a transaction later on. On some systems, the
        ** OsTruncate() call used in exclusive-access mode also requires
        ** a read/write file handle.
        */
        if( !isHot ){
          rc = SQLITE_BUSY;
          if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
            int fout = 0;
            int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
            assert( !pPager->tempFile );
            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
            assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
            if( fout&SQLITE_OPEN_READONLY ){
              rc = SQLITE_BUSY;







|







 







|
>
>
>
>
>







 







<

|


<







 







|





>
>



>


|
>
|







 







|
>
>
>
>







 







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
....
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
....
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
....
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
....
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
** 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.421 2008/03/27 22:42:52 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
    }
    zMasterPtr = &zMasterJournal[nMasterJournal];
    rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
    if( rc!=SQLITE_OK ) goto delmaster_out;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS);
      if( rc!=0 && rc!=1 ){
        rc = SQLITE_IOERR_NOMEM;
        goto delmaster_out;
      }
      if( rc==1 ){
        /* One of the journals pointed to by the master journal exists.
        ** Open it and check if it points at the master journal. If
        ** so, return without deleting the master journal file.
        */
        int c;
        int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
        rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
................................................................................
  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  */
  zMaster = pPager->pTmpSpace;
  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);

  if( rc!=SQLITE_OK 
   || (zMaster[0] && sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)==0 ) 
  ){
    zMaster = 0;

    goto end_playback;
  }
  pPager->journalOff = 0;
  zMaster = 0;

  /* This loop terminates either when the readJournalHdr() call returns
  ** SQLITE_DONE or an IO error occurs. */
................................................................................
  assert( n1==n2 );
#endif

  return pPager->pDirty;
}

/*
** Return 1 if there is a hot journal on the given pager.
** A hot journal is one that needs to be played back.
**
** If the current size of the database file is 0 but a journal file
** exists, that is probably an old journal left over from a prior
** database with the same name.  Just delete the journal.
**
** Return negative if unable to determine the status of the journal.
*/
static int hasHotJournal(Pager *pPager){
  sqlite3_vfs *pVfs = pPager->pVfs;
  int rc;
  if( !pPager->useJournal ) return 0;
  if( !pPager->fd->pMethods ) return 0;
  rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS);
  if( rc<=0 ){
    return rc;
  }
  if( sqlite3OsCheckReservedLock(pPager->fd) ){
    return 0;
  }
  if( sqlite3PagerPagecount(pPager)==0 ){
    sqlite3OsDelete(pVfs, pPager->zJournal, 0);
    return 0;
................................................................................
        }
        assert( pPager->state>=SHARED_LOCK );
      }
  
      /* If a journal file exists, and there is no RESERVED lock on the
      ** database file, then it either needs to be played back or deleted.
      */
      rc = hasHotJournal(pPager);
      if( rc<0 ){
        return pager_error(pPager, SQLITE_IOERR_NOMEM);
      }
      if( rc==1 || isHot ){
        /* Get an EXCLUSIVE lock on the database file. At this point it is
        ** important that a RESERVED lock is not obtained on the way to the
        ** EXCLUSIVE lock. If it were, another process might open the
        ** database file, detect the RESERVED lock, and conclude that the
        ** database is safe to read while this process is still rolling it 
        ** back.
        ** 
................................................................................
        ** exclusive-access mode the file descriptor will be kept open and
        ** possibly used for a transaction later on. On some systems, the
        ** OsTruncate() call used in exclusive-access mode also requires
        ** a read/write file handle.
        */
        if( !isHot ){
          rc = SQLITE_BUSY;
          if( sqlite3OsAccess(pVfs, pPager->zJournal,SQLITE_ACCESS_EXISTS)==1 ){
            int fout = 0;
            int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
            assert( !pPager->tempFile );
            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
            assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
            if( fout&SQLITE_OPEN_READONLY ){
              rc = SQLITE_BUSY;

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
**    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 implement the PRAGMA command.
**
** $Id: pragma.c,v 1.173 2008/03/25 17:23:33 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
            "temp_store_directory", P4_STATIC);
        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
      }
    }else{
      if( zRight[0] 
       && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) 
      ){
        sqlite3ErrorMsg(pParse, "not a writable directory");
        goto pragma_out;
      }
      if( TEMP_STORE==0
       || (TEMP_STORE==1 && db->temp_store<=1)
       || (TEMP_STORE==2 && db->temp_store==1)







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
**    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 implement the PRAGMA command.
**
** $Id: pragma.c,v 1.174 2008/03/27 22:42:52 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
            "temp_store_directory", P4_STATIC);
        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
      }
    }else{
      if( zRight[0] 
       && sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE)==0 
      ){
        sqlite3ErrorMsg(pParse, "not a writable directory");
        goto pragma_out;
      }
      if( TEMP_STORE==0
       || (TEMP_STORE==1 && db->temp_store<=1)
       || (TEMP_STORE==2 && db->temp_store==1)

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
...
607
608
609
610
611
612
613
614

615
616


617
618
619
620
621
622
623
**
** 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.719 2008/03/27 17:59:02 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

  if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS))
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS) ){
    p->trace = stdout;
  }

#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 = hwtime();
................................................................................
    if( p->trace ){
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
    if( p->trace==0 && pc==0 

     && sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS) ){
      sqlite3VdbePrintSql(p);


    }
#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
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
**
** 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.720 2008/03/27 22:42:52 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
  sqlite3FaultBenign(-1, 1);
  if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)==1 )
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS)==1 ){
    p->trace = stdout;
  }
  sqlite3FaultBenign(-1, 0);
#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 = hwtime();
................................................................................
    if( p->trace ){
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
    if( p->trace==0 && pc==0 ){
      sqlite3FaultBenign(-1, 1);
      if( sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS)==1 ){
        sqlite3VdbePrintSql(p);
      }
      sqlite3FaultBenign(-1, 0);
    }
#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.

1286
1287
1288
1289
1290
1291
1292
1293
1294




1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
      u32 random;
      sqlite3_free(zMaster);
      sqlite3_randomness(sizeof(random), &random);
      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
      if( !zMaster ){
        return SQLITE_NOMEM;
      }
    }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) );





    /* Open the master journal. */
    rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
        SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
        SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
    );

    if( rc!=SQLITE_OK ){
      sqlite3_free(zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** master journal file. If an error occurs at this point close







|
<
>
>
>
>
|
|
|
|
|
>







1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
      u32 random;
      sqlite3_free(zMaster);
      sqlite3_randomness(sizeof(random), &random);
      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
      if( !zMaster ){
        return SQLITE_NOMEM;
      }
      rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS);

    }while( rc==1 );
    if( rc!=0 ){
      rc = SQLITE_IOERR_NOMEM;
    }else{
      /* Open the master journal. */
      rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
          SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
      );
    }
    if( rc!=SQLITE_OK ){
      sqlite3_free(zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** master journal file. If an error occurs at this point close