/ Check-in [9d3f3736]
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:Fix a couple of errors in WAL code that can occur in an OOM situation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9d3f3736be42ef8ab48b099d4712e08dfca97873
User & Date: dan 2010-05-03 17:18:24
Context
2010-05-03
17:24
Clear global variable "seconds" before use in walthread.test. check-in: a35551a5 user: drh tags: trunk
17:18
Fix a couple of errors in WAL code that can occur in an OOM situation. check-in: 9d3f3736 user: dan tags: trunk
16:36
Update the crash-test VFS in test6.c to pass-through the shared-memory methods to the real underlying VFS. This fixes the walcrash.test script. check-in: ea09ff37 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
....
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  nName = strlen(zName);
  pNew = sqlite3_malloc( sizeof(*pFile) + nName + 10 );
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
    goto shm_open_err;
  }
  memset(pNew, 0, sizeof(*pNew));
  pNew->zFilename = (char*)&pNew[1];
  sqlite3_snprintf(nName+10, pNew->zFilename, "%s-index", zName);

  /* Look to see if there is an existing unixShmFile that can be used.
  ** If no matching unixShmFile currently exists, create a new one.
................................................................................
  pFile->nRef++;
  *pShm = (sqlite3_shm*)p;
  unixLeaveMutex();
  return SQLITE_OK;

  /* Jump here on any error */
shm_open_err:
  unixShmPurge();
  sqlite3_free(p);
  sqlite3_free(pFile);
  sqlite3_free(pNew);
  *pShm = 0;
  unixLeaveMutex();
  return rc;
}

/*







|
|







 







|

<







4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
....
5055
5056
5057
5058
5059
5060
5061
5062
5063

5064
5065
5066
5067
5068
5069
5070
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  nName = strlen(zName);
  pNew = sqlite3_malloc( sizeof(*pFile) + nName + 10 );
  if( pNew==0 ){
    sqlite3_free(p);
    return SQLITE_NOMEM;
  }
  memset(pNew, 0, sizeof(*pNew));
  pNew->zFilename = (char*)&pNew[1];
  sqlite3_snprintf(nName+10, pNew->zFilename, "%s-index", zName);

  /* Look to see if there is an existing unixShmFile that can be used.
  ** If no matching unixShmFile currently exists, create a new one.
................................................................................
  pFile->nRef++;
  *pShm = (sqlite3_shm*)p;
  unixLeaveMutex();
  return SQLITE_OK;

  /* Jump here on any error */
shm_open_err:
  unixShmPurge();                 /* This call frees pFile if required */
  sqlite3_free(p);

  sqlite3_free(pNew);
  *pShm = 0;
  unixLeaveMutex();
  return rc;
}

/*

Changes to src/wal.c.

588
589
590
591
592
593
594
595



596
597
598
599
600
601
602
603

604
605
606
607

608
609
610
611
612
613

614
615
616
617
618
619
620
...
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689

690
691
692
693
694
695
696
  assert( zDb );
  if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;

  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;
  nWal = strlen(zDb);
  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5);
  if( !pRet ) goto wal_open_out;



  pRet->pVfs = pVfs;
  pRet->pFd = (sqlite3_file *)&pRet[1];
  pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
  sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
  rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex);
  if( rc ) goto wal_open_out;

  /* Open file handle on the write-ahead log file. */

  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
  rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);

wal_open_out:

  if( rc!=SQLITE_OK ){
    if( pRet ){
      pVfs->xShmClose(pVfs, pRet->pWIndex, 0);
      sqlite3OsClose(pRet->pFd);
      sqlite3_free(pRet);
    }

  }
  *ppWal = pRet;
  return rc;
}

static int walIteratorNext(
  WalIterator *p,               /* Iterator */
................................................................................
  aData = pWal->pWiData;
  iLast = pWal->hdr.iLastPg;
  nSegment = (iLast >> 8) + 1;
  nFinal = (iLast & 0x000000FF);

  nByte = sizeof(WalIterator) + (nSegment-1)*sizeof(struct WalSegment) + 512;
  p = (WalIterator *)sqlite3_malloc(nByte);

  if( p ){
    memset(p, 0, nByte);
    p->nSegment = nSegment;
    p->nFinal = nFinal;
  }

  for(i=0; i<nSegment-1; i++){
    p->aSegment[i].aDbPage = &aData[walIndexEntry(i*256+1)];
    p->aSegment[i].aIndex = (u8 *)&aData[walIndexEntry(i*256+1)+256];
  }
  pFinal = &p->aSegment[nSegment-1];

  pFinal->aDbPage = &aData[walIndexEntry((nSegment-1)*256+1)];
  pFinal->aIndex = (u8 *)&pFinal[1];
  aTmp = &pFinal->aIndex[256];
  for(i=0; i<nFinal; i++){
    pFinal->aIndex[i] = i;
  }
  walMergesort8(pFinal->aDbPage, aTmp, pFinal->aIndex, &nFinal);
  p->nFinal = nFinal;


  return p;
}

/* 
** Free a log iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){







|
>
>
>





<


>
|
|
|
<
>






>







 







>



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







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
...
666
667
668
669
670
671
672
673
674
675
676

677

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
  assert( zDb );
  if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;

  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;
  nWal = strlen(zDb);
  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5);
  if( !pRet ){
    return SQLITE_NOMEM;
  }

  pRet->pVfs = pVfs;
  pRet->pFd = (sqlite3_file *)&pRet[1];
  pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
  sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
  rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex);


  /* Open file handle on the write-ahead log file. */
  if( rc==SQLITE_OK ){
    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);
  }


  if( rc!=SQLITE_OK ){
    if( pRet ){
      pVfs->xShmClose(pVfs, pRet->pWIndex, 0);
      sqlite3OsClose(pRet->pFd);
      sqlite3_free(pRet);
    }
    pRet = 0;
  }
  *ppWal = pRet;
  return rc;
}

static int walIteratorNext(
  WalIterator *p,               /* Iterator */
................................................................................
  aData = pWal->pWiData;
  iLast = pWal->hdr.iLastPg;
  nSegment = (iLast >> 8) + 1;
  nFinal = (iLast & 0x000000FF);

  nByte = sizeof(WalIterator) + (nSegment-1)*sizeof(struct WalSegment) + 512;
  p = (WalIterator *)sqlite3_malloc(nByte);

  if( p ){
    memset(p, 0, nByte);
    p->nSegment = nSegment;



    for(i=0; i<nSegment-1; i++){
      p->aSegment[i].aDbPage = &aData[walIndexEntry(i*256+1)];
      p->aSegment[i].aIndex = (u8 *)&aData[walIndexEntry(i*256+1)+256];
    }
    pFinal = &p->aSegment[nSegment-1];
  
    pFinal->aDbPage = &aData[walIndexEntry((nSegment-1)*256+1)];
    pFinal->aIndex = (u8 *)&pFinal[1];
    aTmp = &pFinal->aIndex[256];
    for(i=0; i<nFinal; i++){
      pFinal->aIndex[i] = i;
    }
    walMergesort8(pFinal->aDbPage, aTmp, pFinal->aIndex, &nFinal);
    p->nFinal = nFinal;
  }

  return p;
}

/* 
** Free a log iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){

Added test/walfault.test.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
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
# 2010 May 03
#
# The author disclaims copyright to this source code.  In place of
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode.
#

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

ifcapable !wal {finish_test ; return }

do_malloc_test walfault-oom-1 -sqlbody {
  PRAGMA journal_mode = WAL;
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2);
  PRAGMA checkpoint;
}


finish_test