/ Check-in [b96bcaa1]
Login

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

Overview
Comment:Test a couple of specific malloc() failures that were not tested before. (CVS 5350)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b96bcaa197519b5be89e1f6a1579f0e36fe2b644
User & Date: danielk1977 2008-07-07 14:56:57
Context
2008-07-07
15:39
Add a test case to test corruption discovered as part of the ptrmapPut() routine. (CVS 5351) check-in: cbb9536f user: danielk1977 tags: trunk
14:56
Test a couple of specific malloc() failures that were not tested before. (CVS 5350) check-in: b96bcaa1 user: danielk1977 tags: trunk
14:50
Additional test cases added on the sqlite3_create_function() interface. (CVS 5349) check-in: 4e941f3d user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
....
5039
5040
5041
5042
5043
5044
5045
5046
5047


5048
5049
5050
5051
5052
5053
5054
....
5077
5078
5079
5080
5081
5082
5083

5084

5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
**
** 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.756 2008/06/26 18:04:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      goto vdbe_return;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 P3 * *
................................................................................

  /* If we reach this point, it means that execution is finished with
  ** an error of some kind.
  */
vdbe_error_halt:
  assert( rc );
  p->rc = rc;
  rc = SQLITE_ERROR;
  sqlite3VdbeHalt(p);



  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
  return rc;
................................................................................

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  assert( p->zErrMsg==0 );
  if( db->mallocFailed ) rc = SQLITE_NOMEM;

  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);

  goto vdbe_error_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( db->u1.isInterrupted );
  rc = SQLITE_INTERRUPT;
  p->rc = rc;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  goto vdbe_error_halt;
}







|







 







|







 







<

>
>







 







>
|
>












39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
....
5039
5040
5041
5042
5043
5044
5045

5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
....
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
**
** 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.757 2008/07/07 14:56:57 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      goto vdbe_return;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY && /* rc!=SQLITE_BUSY */ ){
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 P3 * *
................................................................................

  /* If we reach this point, it means that execution is finished with
  ** an error of some kind.
  */
vdbe_error_halt:
  assert( rc );
  p->rc = rc;

  sqlite3VdbeHalt(p);
  if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
  rc = SQLITE_ERROR;

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
  return rc;
................................................................................

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  assert( p->zErrMsg==0 );
  if( db->mallocFailed ) rc = SQLITE_NOMEM;
  if( rc!=SQLITE_IOERR_NOMEM ){
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_error_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( db->u1.isInterrupted );
  rc = SQLITE_INTERRUPT;
  p->rc = rc;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  goto vdbe_error_halt;
}

Changes to test/malloc.test.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
589
590
591
592
593
594
595
















596
597
598
599
600
601
602
603
604
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.62 2008/06/19 18:17:50 danielk1977 Exp $

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


# Only run these tests if memory debugging is turned on.
#
................................................................................
    CREATE TRIGGER v1t3 INSTEAD OF UPDATE ON v1 BEGIN SELECT 1; END;
  } -sqlbody {
    DELETE FROM v1 WHERE a = 1;
    INSERT INTO v1 VALUES(1, 2, 3);
    UPDATE v1 SET a = 1 WHERE b = 2;
  }
}

















# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
finish_test







|







 







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









12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
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
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.63 2008/07/07 14:56:57 danielk1977 Exp $

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


# Only run these tests if memory debugging is turned on.
#
................................................................................
    CREATE TRIGGER v1t3 INSTEAD OF UPDATE ON v1 BEGIN SELECT 1; END;
  } -sqlbody {
    DELETE FROM v1 WHERE a = 1;
    INSERT INTO v1 VALUES(1, 2, 3);
    UPDATE v1 SET a = 1 WHERE b = 2;
  }
}

do_malloc_test 25 -sqlprep {
  CREATE TABLE abc(a, b, c);
  CREATE INDEX i1 ON abc(a, b);
  INSERT INTO abc VALUES(1, 2, 3);
  INSERT INTO abc VALUES(4, 5, 6);
} -tclbody {
  # For each UPDATE executed, the cursor used for the SELECT statement
  # must be "saved". Because the cursor is open on an index, this requires
  # a malloc() to allocate space to save the index key. This test case is
  # aimed at testing the response of the library to a failure in that
  # particular malloc() call.
  db eval {SELECT a FROM abc ORDER BY a} {
    db eval {UPDATE abc SET b = b - 1 WHERE a = $a}
  }
}

# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
finish_test

Changes to test/shared_err.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
496
497
498
499
500
501
502




503
504
505
506
507
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.19 2008/05/22 13:56:17 danielk1977 Exp $

proc skip {args} {}


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

ifcapable !shared_cache||!subquery {
  finish_test
  return
}

set ::enable_shared_cache [sqlite3_enable_shared_cache 1]


do_ioerr_test shared_ioerr-1 -tclprep {
  sqlite3 db2 test.db
  execsql {
    PRAGMA read_uncommitted = 1;
    CREATE TABLE t1(a,b,c);
    BEGIN;
................................................................................
  catch {db eval {SELECT * FROM sqlite_master}}
  catch {sqlite3_errmsg16 db}
  error 1
} -cleanup {
  execsql { SELECT * FROM sqlite_master }
}






catch {db close}
catch {db2 close}
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test







|







 







<







 







>
>
>
>





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

32
33
34
35
36
37
38
...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.20 2008/07/07 14:56:57 danielk1977 Exp $

proc skip {args} {}


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

ifcapable !shared_cache||!subquery {
  finish_test
  return
}

set ::enable_shared_cache [sqlite3_enable_shared_cache 1]


do_ioerr_test shared_ioerr-1 -tclprep {
  sqlite3 db2 test.db
  execsql {
    PRAGMA read_uncommitted = 1;
    CREATE TABLE t1(a,b,c);
    BEGIN;
................................................................................
  catch {db eval {SELECT * FROM sqlite_master}}
  catch {sqlite3_errmsg16 db}
  error 1
} -cleanup {
  execsql { SELECT * FROM sqlite_master }
}

do_malloc_test shared_err-12 -sqlbody {
  CREATE TABLE abc(a, b, c);
  INSERT INTO abc VALUES(1, 2, 3);
}

catch {db close}
catch {db2 close}
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test