Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rig the sqliteMalloc() routine so that we can make it fail multiple times in a row. Modify the malloc.test procedure to make malloc fail in this way and verify that the failures are still handled correctly. (CVS 2121) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
519bc9d9975bbdb4ba056799534d5c46 |
User & Date: | drh 2004-11-20 19:18:01.000 |
Context
2004-11-20
| ||
19:18 | Omit the maximum loop count on the random name chooser in the VACUUM command. Add a comment to explain why this is safe and does not result in an infinite loop. Ticket #1009. (CVS 2122) (check-in: 1241086f23 user: drh tags: trunk) | |
19:18 | Rig the sqliteMalloc() routine so that we can make it fail multiple times in a row. Modify the malloc.test procedure to make malloc fail in this way and verify that the failures are still handled correctly. (CVS 2121) (check-in: 519bc9d997 user: drh tags: trunk) | |
18:13 | Fix segfaults that might occur after a malloc failure. (CVS 2119) (check-in: 368774487e user: drh tags: trunk) | |
Changes
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.341 2004/11/20 19:18:01 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks |
︙ | ︙ | |||
246 247 248 249 250 251 252 | extern int sqlite3_malloc_failed; /* ** The following global variables are used for testing and debugging ** only. They only work if SQLITE_DEBUG is defined. */ #ifdef SQLITE_DEBUG | | | | > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | extern int sqlite3_malloc_failed; /* ** The following global variables are used for testing and debugging ** only. They only work if SQLITE_DEBUG is defined. */ #ifdef SQLITE_DEBUG extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ extern int sqlite3_nFree; /* Number of sqliteFree() calls */ extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */ #endif /* ** Name of the master database table. The master database table ** is a special table that holds the names and attributes of all ** user tables and indices. */ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.116 2004/11/20 19:18:01 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
742 743 744 745 746 747 748 | z = sqlite3_mprintf(argv[1], argv[2]); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); return TCL_OK; } /* | | | > > > > > | > | > > > > > > | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | z = sqlite3_mprintf(argv[1], argv[2]); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); return TCL_OK; } /* ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? ** ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the ** first failure will continue to fail on every call. If REPEAT-INTERVAL is ** 2 then every other malloc will fail. And so forth. ** ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0. */ #ifdef SQLITE_DEBUG static int sqlite_malloc_fail( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ int n; int rep; if( argc!=2 && argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; if( argc==3 ){ if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; }else{ rep = 0; } sqlite3_iMallocFail = n; sqlite3_iMallocReset = rep; sqlite3_malloc_failed = 0; return TCL_OK; } #endif /* ** Usage: sqlite_malloc_stat |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.122 2004/11/20 19:18:01 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> #if SQLITE_DEBUG>2 && defined(__GLIBC__) #include <execinfo.h> |
︙ | ︙ | |||
47 48 49 50 51 52 53 | ** If SQLITE_DEBUG is defined, then use versions of malloc() and ** free() that track memory usage and check for buffer overruns. */ #ifdef SQLITE_DEBUG /* ** For keeping track of the number of mallocs and frees. This | | > > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | ** If SQLITE_DEBUG is defined, then use versions of malloc() and ** free() that track memory usage and check for buffer overruns. */ #ifdef SQLITE_DEBUG /* ** For keeping track of the number of mallocs and frees. This ** is used to check for memory leaks. The iMallocFail and iMallocReset ** values are used to simulate malloc() failures during testing in ** order to verify that the library correctly handles an out-of-memory ** condition. */ int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ int sqlite3_nFree; /* Number of sqliteFree() calls */ int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */ #if SQLITE_DEBUG>1 static int memcnt = 0; #endif /* ** Number of 32-bit guard words */ |
︙ | ︙ | |||
77 78 79 80 81 82 83 | sqlite3_iMallocFail--; if( sqlite3_iMallocFail==0 ){ sqlite3_malloc_failed++; #if SQLITE_DEBUG>1 fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n", n, zFile,line); #endif | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | sqlite3_iMallocFail--; if( sqlite3_iMallocFail==0 ){ sqlite3_malloc_failed++; #if SQLITE_DEBUG>1 fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n", n, zFile,line); #endif sqlite3_iMallocFail = sqlite3_iMallocReset; return 0; } } if( n==0 ) return 0; k = (n+sizeof(int)-1)/sizeof(int); pi = malloc( (N_GUARD*2+1+k)*sizeof(int)); if( pi==0 ){ |
︙ | ︙ |
Changes to test/malloc.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) 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. # | | | | 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 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) 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.11 2004/11/20 19:18:01 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 -DMEMORY_DEBUG..." finish_test return } for {set go 1; set i 1} {$go} {incr i} { do_test malloc-1.$i { sqlite_malloc_fail 0 catch {db close} catch {file delete -force test.db} catch {file delete -force test.db-journal} sqlite_malloc_fail $i [expr {$i%4}] set v [catch {sqlite3 db test.db} msg] if {$v} { set msg "" } else { set v [catch {execsql { CREATE TABLE t1( a int, b float, c double, d text, e varchar(20), |
︙ | ︙ |