/ Check-in [0f7fdb02]
Login

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

Overview
Comment:Fix an memory allocation error revealed by malloc3.test. (CVS 3733)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:0f7fdb022ca7c94f7d264192e18b6e2bd1e8cff4
User & Date: drh 2007-03-28 01:59:34
Context
2007-03-28
13:07
Update comments in sqlite3.h. No changes to code. (CVS 3734) check-in: 1c2656fd user: drh tags: trunk
01:59
Fix an memory allocation error revealed by malloc3.test. (CVS 3733) check-in: 0f7fdb02 user: drh tags: trunk
2007-03-27
22:24
The SQLITE_ENABLE_LOAD_EXTENSION macro enables the load_extension() SQL function by default without having to invoke sqlite3_enable_load_extension() first. (CVS 3732) check-in: 113aab2c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
3056
3057
3058
3059
3060
3061
3062



3063
3064
3065
3066
3067
3068
3069
....
3088
3089
3090
3091
3092
3093
3094

3095
3096
3097
3098
3099
3100
3101
3102


3103
3104

3105
3106
3107
3108
3109
3110
3111
** 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.303 2007/03/27 17:37:32 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  }
  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
                                 pPager->tempFile);
  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){



    goto failed_to_open_journal;
  }
  sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
  sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
  sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
................................................................................
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;

  if( rc==SQLITE_NOMEM ){
    /* If this was a malloc() failure, then we will not be closing the pager
    ** file. So delete any journal file we may have just created. Otherwise,
    ** the system will get confused, we have a read-lock on the file and a
    ** mysterious journal has appeared in the filesystem.
    */
    /* sqlite3OsDelete(pPager->zJournal); */
  }else{


    pager_reset(pPager);
  }

  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**







|







 







>
>
>







 







>








>
>
|

>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
....
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
** 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.304 2007/03/28 01:59:34 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  }
  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
                                 pPager->tempFile);
  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM ){
      sqlite3OsDelete(pPager->zJournal);
    }
    goto failed_to_open_journal;
  }
  sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
  sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
  sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
................................................................................
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;
#if 0
  if( rc==SQLITE_NOMEM ){
    /* If this was a malloc() failure, then we will not be closing the pager
    ** file. So delete any journal file we may have just created. Otherwise,
    ** the system will get confused, we have a read-lock on the file and a
    ** mysterious journal has appeared in the filesystem.
    */
    /* sqlite3OsDelete(pPager->zJournal); */
  }else{
    /* If we reset the pager here, we will delete pages out from under
    ** various cursors and will ultimately segfault. */
    /* pager_reset(pPager); */
  }
#endif
  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**

Changes to test/malloc3.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
...
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
...
648
649
650
651
652
653
654
655
#
#***********************************************************************
#
# This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis of these tests are the _prepare(), _step() and
# _finalize() calls.
#
# $Id: malloc3.test,v 1.9 2006/01/23 07:52:41 danielk1977 Exp $

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

# Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
................................................................................
    error "Uneven number of arguments to TEST"
  }

  for {set i 0} {$i < $pcstart} {incr i} {
    set k2 [lindex $arglist [expr 2 * $i]]
    set v2 [lindex $arglist [expr 2 * $i + 1]]
    set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit
# puts "STARTUP"
    switch -- $k2 {
      -sql  {db eval [lindex $v2 1]}
      -prep {db eval $v2}
    }
    set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 
    if {$ac && !$nac} {set begin_pc $i}
  }
................................................................................

  set iFail $iFailStart
  set pc $pcstart
  while {$pc*2 < [llength $arglist]} {

    # Id of this iteration:
    set iterid "(pc $pc).(iFail $iFail)"

    set k [lindex $arglist [expr 2 * $pc]]
    set v [lindex $arglist [expr 2 * $pc + 1]]

    switch -- $k {

      -test { 
        foreach {id script} $v {}
................................................................................
      }

      -sql {
        set ::rollback_hook_count 0

        set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit
        sqlite_malloc_fail $iFail
# puts "SQL $iterid [lindex $v 1]"
        set rc [catch {db eval [lindex $v 1]} msg]   ;# True error occurs
# puts "rc = $rc msg = \"$msg\""
        set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 


        if {$rc != 0 && $nac && !$ac} {
          # Before [db eval] the auto-commit flag was clear. Now it
          # is set. Since an error occured we assume this was not a
	  # commit - therefore a rollback occured. Check that the
................................................................................
            incr iFail
            if {$nac && !$ac} {

              if {![lindex $v 0]} {
                error "Statement \"[lindex $v 1]\" caused a rollback"
              }

# puts "Statement \"[lindex $v 1]\" caused a rollback"
              for {set i $begin_pc} {$i < $pc} {incr i} {
                set k2 [lindex $arglist [expr 2 * $i]]
                set v2 [lindex $arglist [expr 2 * $i + 1]]
                set catchupsql ""
                switch -- $k2 {
                  -sql  {set catchupsql [lindex $v2 1]}
                  -prep {set catchupsql $v2}
                }
# puts "CATCHUP $iterid $i $catchupsql"
                db eval $catchupsql
              }
            }
        } else {
            error $msg
        }

        while {[lindex $arglist [expr 2 * ($pc -1)]] == "-test"} {
          incr pc -1
        }
      }

      -prep {
# puts "PREP $iterid $v"
        db eval $v
        incr pc
      }

      default { error "Unknown switch: $k" }
    }
# if {$iFail > ($iFailStart+1)} return
  }
}

# Turn of the Tcl interface's prepared statement caching facility.
db cache size 0

run_test $::run_test_script 9 1
................................................................................
# run_test [lrange $::run_test_script 0 3] 0 63
sqlite_malloc_fail 0
db close

pp_check_for_leaks

finish_test








|







 







<







 







<







 







<

<







 







<








<













<






<







 







<
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
523
524
525
526
527
528
529

530
531
532
533
534
535
536
...
539
540
541
542
543
544
545

546
547
548
549
550
551
552
...
556
557
558
559
560
561
562

563

564
565
566
567
568
569
570
...
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
625
626

627
628
629
630
631
632

633
634
635
636
637
638
639
...
640
641
642
643
644
645
646

#
#***********************************************************************
#
# This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis of these tests are the _prepare(), _step() and
# _finalize() calls.
#
# $Id: malloc3.test,v 1.10 2007/03/28 01:59:34 drh Exp $

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

# Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
................................................................................
    error "Uneven number of arguments to TEST"
  }

  for {set i 0} {$i < $pcstart} {incr i} {
    set k2 [lindex $arglist [expr 2 * $i]]
    set v2 [lindex $arglist [expr 2 * $i + 1]]
    set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit

    switch -- $k2 {
      -sql  {db eval [lindex $v2 1]}
      -prep {db eval $v2}
    }
    set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 
    if {$ac && !$nac} {set begin_pc $i}
  }
................................................................................

  set iFail $iFailStart
  set pc $pcstart
  while {$pc*2 < [llength $arglist]} {

    # Id of this iteration:
    set iterid "(pc $pc).(iFail $iFail)"

    set k [lindex $arglist [expr 2 * $pc]]
    set v [lindex $arglist [expr 2 * $pc + 1]]

    switch -- $k {

      -test { 
        foreach {id script} $v {}
................................................................................
      }

      -sql {
        set ::rollback_hook_count 0

        set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit
        sqlite_malloc_fail $iFail

        set rc [catch {db eval [lindex $v 1]} msg]   ;# True error occurs

        set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 


        if {$rc != 0 && $nac && !$ac} {
          # Before [db eval] the auto-commit flag was clear. Now it
          # is set. Since an error occured we assume this was not a
	  # commit - therefore a rollback occured. Check that the
................................................................................
            incr iFail
            if {$nac && !$ac} {

              if {![lindex $v 0]} {
                error "Statement \"[lindex $v 1]\" caused a rollback"
              }


              for {set i $begin_pc} {$i < $pc} {incr i} {
                set k2 [lindex $arglist [expr 2 * $i]]
                set v2 [lindex $arglist [expr 2 * $i + 1]]
                set catchupsql ""
                switch -- $k2 {
                  -sql  {set catchupsql [lindex $v2 1]}
                  -prep {set catchupsql $v2}
                }

                db eval $catchupsql
              }
            }
        } else {
            error $msg
        }

        while {[lindex $arglist [expr 2 * ($pc -1)]] == "-test"} {
          incr pc -1
        }
      }

      -prep {

        db eval $v
        incr pc
      }

      default { error "Unknown switch: $k" }
    }

  }
}

# Turn of the Tcl interface's prepared statement caching facility.
db cache size 0

run_test $::run_test_script 9 1
................................................................................
# run_test [lrange $::run_test_script 0 3] 0 63
sqlite_malloc_fail 0
db close

pp_check_for_leaks

finish_test