SQLite

Check-in [1a335e1801]
Login

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

Overview
Comment:Add the fault injector module in fault.c. Use it as a basis for memory allocation failure testing. (CVS 4742)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1a335e180183b414fcc3510ce28b98b21cd134a6
User & Date: drh 2008-01-22 21:30:53.000
Context
2008-01-22
23:37
Improved test coverage for the tokenizer and sqlite3_complete() interface. Fix bugs in parsing blob literals and SQL variables beginning with $. (CVS 4743) (check-in: c82033faf8 user: drh tags: trunk)
21:30
Add the fault injector module in fault.c. Use it as a basis for memory allocation failure testing. (CVS 4742) (check-in: 1a335e1801 user: drh tags: trunk)
19:34
Fix a bug introduced by checkin (4739). (CVS 4741) (check-in: c8394ac24b user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
###############################################################################
TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1

# Object files for the SQLite library.
#
LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btmutex.lo btree.lo build.lo \
         callback.lo complete.lo date.lo \

         delete.lo expr.lo func.lo hash.lo journal.lo insert.lo loadext.lo \
         main.lo malloc.lo mem1.lo mem2.lo mem3.lo mem4.lo mutex.lo \
         mutex_os2.lo mutex_unix.lo mutex_w32.lo \
         opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
         pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
         select.lo table.lo tokenize.lo trigger.lo update.lo \
         util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \







>
|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
###############################################################################
TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1

# Object files for the SQLite library.
#
LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btmutex.lo btree.lo build.lo \
         callback.lo complete.lo date.lo \
         delete.lo expr.lo fault.lo func.lo \
         hash.lo journal.lo insert.lo loadext.lo \
         main.lo malloc.lo mem1.lo mem2.lo mem3.lo mem4.lo mutex.lo \
         mutex_os2.lo mutex_unix.lo mutex_w32.lo \
         opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
         pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
         select.lo table.lo tokenize.lo trigger.lo update.lo \
         util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \
144
145
146
147
148
149
150

151
152
153
154
155
156
157
  $(TOP)/src/btree.h \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \

  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \







>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  $(TOP)/src/btree.h \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
226
227
228
229
230
231
232

233
234
235
236
237
238
239
  $(TOP)/src/os_os2.c \
  $(TOP)/src/os_unix.c \
  $(TOP)/src/os_win.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/pragma.c \
  $(TOP)/src/prepare.c \
  $(TOP)/src/printf.c \

  $(TOP)/src/select.c \
  $(TOP)/src/test1.c \
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(TOP)/src/test6.c \







>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  $(TOP)/src/os_os2.c \
  $(TOP)/src/os_unix.c \
  $(TOP)/src/os_win.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/pragma.c \
  $(TOP)/src/prepare.c \
  $(TOP)/src/printf.c \
  $(TOP)/src/random.c \
  $(TOP)/src/select.c \
  $(TOP)/src/test1.c \
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(TOP)/src/test6.c \
379
380
381
382
383
384
385



386
387
388
389
390
391
392
	$(LTCOMPILE) -c $(TOP)/src/date.c

delete.lo:	$(TOP)/src/delete.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/delete.c

expr.lo:	$(TOP)/src/expr.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/expr.c




func.lo:	$(TOP)/src/func.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/func.c

hash.lo:	$(TOP)/src/hash.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/hash.c








>
>
>







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
	$(LTCOMPILE) -c $(TOP)/src/date.c

delete.lo:	$(TOP)/src/delete.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/delete.c

expr.lo:	$(TOP)/src/expr.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/expr.c

fault.lo:	$(TOP)/src/fault.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/fault.c

func.lo:	$(TOP)/src/func.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/func.c

hash.lo:	$(TOP)/src/hash.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/hash.c

Changes to main.mk.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src

# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o btmutex.o btree.o build.o \
         callback.o complete.o date.o delete.o \
         expr.o func.o hash.o insert.o journal.o loadext.o \
         main.o malloc.o mem1.o mem2.o mem3.o mem4.o mutex.o mutex_os2.o \
         mutex_unix.o mutex_w32.o \
         opcodes.o os.o os_os2.o os_unix.o os_win.o \
         pager.o parse.o pragma.o prepare.o printf.o random.o \
         select.o table.o $(TCLOBJ) tokenize.o trigger.o \
         update.o util.o vacuum.o \
         vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src

# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o btmutex.o btree.o build.o \
         callback.o complete.o date.o delete.o \
         expr.o fault.o func.o hash.o insert.o journal.o loadext.o \
         main.o malloc.o mem1.o mem2.o mem3.o mem4.o mutex.o mutex_os2.o \
         mutex_unix.o mutex_w32.o \
         opcodes.o os.o os_os2.o os_unix.o os_win.o \
         pager.o parse.o pragma.o prepare.o printf.o random.o \
         select.o table.o $(TCLOBJ) tokenize.o trigger.o \
         update.o util.o vacuum.o \
         vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \
91
92
93
94
95
96
97

98
99
100
101
102
103
104
  $(TOP)/src/btreeInt.h \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \

  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \







>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  $(TOP)/src/btreeInt.h \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/loadext.c \
Added src/fault.c.






































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
** 2008 Jan 22
**
** 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 contains code to implement a fault-injector used for
** testing and verification of SQLite.
**
** Subsystems within SQLite can call sqlite3FaultStep() to see if
** they should simulate a fault.  sqlite3FaultStep() normally returns
** zero but will return non-zero if a fault should be simulated.
** Fault injectors can be used, for example, to simulate memory
** allocation failures or I/O errors.
**
** The fault injector is omitted from the code if SQLite is
** compiled with -DSQLITE_OMIT_FAULTINJECTOR=1.  There is a very
** small performance hit for leaving the fault injector in the code.
** Commerical products will probably want to omit the fault injector
** from production builds.  But safety-critical systems who work
** under the motto "fly what you test and test what you fly" may
** choose to leave the fault injector enabled even in production.
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_FAULTINJECTOR

/*
** There can be various kinds of faults.  For example, there can be
** a memory allocation failure.  Or an I/O failure.  For each different
** fault type, there is a separate FaultInjector structure to keep track
** of the status of that fault.
*/
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.
*/
void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  aFault[id].iCountdown = nDelay;
  aFault[id].nRepeat = nRepeat;
  aFault[id].nBenign = 0;
  aFault[id].nFail = 0;
  aFault[id].enable = nDelay>=0;
  aFault[id].benign = 0;
}

/*
** Return the number of faults (both hard and benign faults) that have
** occurred since the injector was last configured.
*/
int sqlite3FaultFailures(int id){
  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  return aFault[id].nFail;
}

/*
** Return the number of benign faults that have occurred since the
** injector was last configured.
*/
int sqlite3FaultBenignFailures(int id){
  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  return aFault[id].nBenign;
}

/*
** Return the number of successes that will occur before the next failure.
** If no failures are scheduled, return -1.
*/
int sqlite3FaultPending(int id){
  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  if( aFault[id].enable ){
    return aFault[id].iCountdown;
  }else{
    return -1;
  }
}

/* 
** After this routine causes subsequent faults to be either benign
** or hard (not benign), according to the "enable" parameter.
**
** Most faults are hard.  In other words, most faults cause
** an error to be propagated back up to the application interface.
** 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){
  static int cnt = 0;
  cnt++;
}


/*
** Check to see if a fault should be simulated.  Return true to simulate
** the fault.  Return false if the fault should not be simulated.
*/
int sqlite3FaultStep(int id){
  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
  if( likely(!aFault[id].enable) ){
    return 0;
  }
  if( aFault[id].iCountdown>0 ){
    aFault[id].iCountdown--;
    return 0;
  }
  sqlite3Fault();
  aFault[id].nFail++;
  if( aFault[id].benign ){
    aFault[id].nBenign++;
  }
  aFault[id].nRepeat--;
  if( aFault[id].nRepeat<=0 ){
    aFault[id].enable = 0;
  }
  return 1;  
}

#endif /* SQLITE_OMIT_FAULTINJECTOR */
Changes to src/hash.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.24 2007/09/04 14:31:47 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.25 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
224
225
226
227
228
229
230
231
232
233


234
235
236
237
238
239
240
  assert( (new_size & (new_size-1))==0 );

  /* There is a call to sqlite3_malloc() inside rehash(). If there is
  ** already an allocation at pH->ht, then if this malloc() fails it
  ** is benign (since failing to resize a hash table is a performance
  ** hit only, not a fatal error).
  */
  sqlite3MallocBenignFailure(pH->htsize>0);

  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );


  if( new_ht==0 ) return;
  if( pH->ht ) sqlite3_free(pH->ht);
  pH->ht = new_ht;
  pH->htsize = new_size;
  xHash = hashFunction(pH->keyClass);
  for(elem=pH->first, pH->first=0; elem; elem = next_elem){
    int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);







<
|

>
>







224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
  assert( (new_size & (new_size-1))==0 );

  /* There is a call to sqlite3_malloc() inside rehash(). If there is
  ** already an allocation at pH->ht, then if this malloc() fails it
  ** is benign (since failing to resize a hash table is a performance
  ** hit only, not a fatal error).
  */

  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, pH->htsize>0);
  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0);

  if( new_ht==0 ) return;
  if( pH->ht ) sqlite3_free(pH->ht);
  pH->ht = new_ht;
  pH->htsize = new_size;
  xHash = hashFunction(pH->keyClass);
  for(elem=pH->first, pH->first=0; elem; elem = next_elem){
    int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.411 2008/01/22 14:50:17 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The version of the library
*/







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.412 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The version of the library
*/
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  int inTrans = 0;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3MallocEnterBenignBlock(1);                 /* Enter benign region */
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  sqlite3VtabRollback(db);
  sqlite3MallocLeaveBenignBlock();                 /* Leave benign region */

  if( db->flags&SQLITE_InternChanges ){
    sqlite3ExpirePreparedStatements(db);
    sqlite3ResetInternalSchema(db, 0);
  }

  /* If one has been configured, invoke the rollback-hook callback */







|










|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  int inTrans = 0;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 1);
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  sqlite3VtabRollback(db);
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0);

  if( db->flags&SQLITE_InternChanges ){
    sqlite3ExpirePreparedStatements(db);
    sqlite3ResetInternalSchema(db, 0);
  }

  /* If one has been configured, invoke the rollback-hook callback */
Changes to src/mem2.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.18 2007/11/29 18:36:49 drh Exp $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.19 2008/01/22 21:30:53 drh Exp $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

  /*
  ** Title text to insert in front of each block
  */
  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */
  char zTitle[100];  /* The title text */

  /*
  ** These values are used to simulate malloc failures.  When
  ** iFail is 1, simulate a malloc failures and reset the value
  ** to iReset.
  */
  int iFail;    /* Decrement and fail malloc when this is 1 */
  int iReset;   /* When malloc fails set iiFail to this value */
  int iFailCnt;         /* Number of failures */
  int iBenignFailCnt;   /* Number of benign failures */
  int iNextIsBenign;    /* True if the next call to malloc may fail benignly */
  int iIsBenign;        /* All malloc calls may fail benignly */

  /* 
  ** sqlite3MallocDisallow() increments the following counter.
  ** sqlite3MallocAllow() decrements it.
  */
  int disallow; /* Do not allow memory allocation */

  /*







<
<
<
<
<
<
<
<
<
<
<
<







132
133
134
135
136
137
138












139
140
141
142
143
144
145

  /*
  ** Title text to insert in front of each block
  */
  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */
  char zTitle[100];  /* The title text */













  /* 
  ** sqlite3MallocDisallow() increments the following counter.
  ** sqlite3MallocAllow() decrements it.
  */
  int disallow; /* Do not allow memory allocation */

  /*
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  assert( p->iForeGuard==FOREGUARD );
  assert( (p->iSize & 3)==0 );
  pInt = (int*)pAllocation;
  assert( pInt[p->iSize/sizeof(int)]==REARGUARD );
  return p;
}

/*
** This routine is called once the first time a simulated memory
** failure occurs.  The sole purpose of this routine is to provide
** a convenient place to set a debugger breakpoint when debugging
** errors related to malloc() failures.
*/
static void sqlite3MemsysFailed(void){
  mem.iFailCnt = 0;
  mem.iBenignFailCnt = 0;
}

/*
** Allocate nByte bytes of memory.
*/
void *sqlite3_malloc(int nByte){
  struct MemBlockHdr *pHdr;
  void **pBt;
  char *z;







<
<
<
<
<
<
<
<
<
<
<







239
240
241
242
243
244
245











246
247
248
249
250
251
252
  assert( p->iForeGuard==FOREGUARD );
  assert( (p->iSize & 3)==0 );
  pInt = (int*)pAllocation;
  assert( pInt[p->iSize/sizeof(int)]==REARGUARD );
  return p;
}












/*
** Allocate nByte bytes of memory.
*/
void *sqlite3_malloc(int nByte){
  struct MemBlockHdr *pHdr;
  void **pBt;
  char *z;
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    if( nByte/8>NCSIZE-1 ){
      mem.sizeCnt[NCSIZE-1]++;
    }else{
      mem.sizeCnt[nByte/8]++;
    }
    totalSize = nByte + sizeof(*pHdr) + sizeof(int) +
                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
    if( mem.iFail>0 ){
      if( mem.iFail==1 ){
        p = 0;
        mem.iFail = mem.iReset;
        if( mem.iFailCnt==0 ){
          sqlite3MemsysFailed();  /* A place to set a breakpoint */
        }
        mem.iFailCnt++;
        if( mem.iNextIsBenign || mem.iIsBenign ){
          mem.iBenignFailCnt++;
        }
      }else{
        p = malloc(totalSize);
        mem.iFail--;
      }
    }else{
      p = malloc(totalSize);
      if( p==0 ){
        sqlite3MemsysAlarm(nByte);
        p = malloc(totalSize);
      }
    }







|
<
|
<
<
<
<
<
<
<
<
<
<
<
<







264
265
266
267
268
269
270
271

272












273
274
275
276
277
278
279
    if( nByte/8>NCSIZE-1 ){
      mem.sizeCnt[NCSIZE-1]++;
    }else{
      mem.sizeCnt[nByte/8]++;
    }
    totalSize = nByte + sizeof(*pHdr) + sizeof(int) +
                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
    if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){

      p = 0;












    }else{
      p = malloc(totalSize);
      if( p==0 ){
        sqlite3MemsysAlarm(nByte);
        p = malloc(totalSize);
      }
    }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
      if( mem.nowUsed>mem.mxUsed ){
        mem.mxUsed = mem.nowUsed;
      }
      p = (void*)pInt;
    }
    sqlite3_mutex_leave(mem.mutex);
  }
  mem.iNextIsBenign = 0;
  return p; 
}

/*
** Free memory.
*/
void sqlite3_free(void *pPrior){







<







310
311
312
313
314
315
316

317
318
319
320
321
322
323
      if( mem.nowUsed>mem.mxUsed ){
        mem.mxUsed = mem.nowUsed;
      }
      p = (void*)pInt;
    }
    sqlite3_mutex_leave(mem.mutex);
  }

  return p; 
}

/*
** Free memory.
*/
void sqlite3_free(void *pPrior){
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
  }
  if( mem.sizeCnt[NCSIZE-1] ){
    fprintf(out, "  >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]);
  }
  fclose(out);
}

/*
** This routine is used to simulate malloc failures.
**
** After calling this routine, there will be iFail successful
** memory allocations and then a failure.  If iRepeat is 1
** all subsequent memory allocations will fail.  If iRepeat is
** 0, only a single allocation will fail.  If iRepeat is negative
** then the previous setting for iRepeat is unchanged.
**
** Each call to this routine overrides the previous.  To disable
** the simulated allocation failure mechanism, set iFail to -1.
**
** This routine returns the number of simulated failures that have
** occurred since the previous call.
*/
int sqlite3_memdebug_fail(int iFail, int iRepeat, int *piBenign){
  int n = mem.iFailCnt;
  if( piBenign ){
    *piBenign = mem.iBenignFailCnt;
  }
  mem.iFail = iFail+1;
  if( iRepeat>=0 ){
    mem.iReset = iRepeat;
  }
  mem.iFailCnt = 0;
  mem.iBenignFailCnt = 0;
  return n;
}

int sqlite3_memdebug_pending(){
  return (mem.iFail-1);
}

/*
** The following three functions are used to indicate to the test 
** infrastructure which malloc() calls may fail benignly without
** affecting functionality. This can happen when resizing hash tables 
** (failing to resize a hash-table is a performance hit, but not an 
** error) or sometimes during a rollback operation.
**
** If the argument is true, sqlite3MallocBenignFailure() indicates that the
** next call to allocate memory may fail benignly.
**
** If sqlite3MallocEnterBenignBlock() is called with a non-zero argument,
** then all memory allocations requested before the next call to
** sqlite3MallocLeaveBenignBlock() may fail benignly.
*/
void sqlite3MallocBenignFailure(int isBenign){
  if( isBenign ){
    mem.iNextIsBenign = 1;
  }
}
void sqlite3MallocEnterBenignBlock(int isBenign){
  if( isBenign ){
    mem.iIsBenign = 1;
  }
}
void sqlite3MallocLeaveBenignBlock(){
  mem.iIsBenign = 0;
}

/*
** The following two routines are used to assert that no memory
** allocations occur between one call and the next.  The use of
** these routines does not change the computed results in any way.
** These routines are like asserts.
*/
void sqlite3MallocDisallow(void){
  assert( mem.mutex!=0 );
  sqlite3_mutex_enter(mem.mutex);
  mem.disallow++;
  sqlite3_mutex_leave(mem.mutex);
}
void sqlite3MallocAllow(void){
  assert( mem.mutex );
  sqlite3_mutex_enter(mem.mutex);
  assert( mem.disallow>0 );
  mem.disallow--;
  sqlite3_mutex_leave(mem.mutex);
}

#endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

448
449
450
451
452
453
454



















455





























































456
  }
  if( mem.sizeCnt[NCSIZE-1] ){
    fprintf(out, "  >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]);
  }
  fclose(out);
}


















































































#endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** 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.403 2008/01/21 13:04:35 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** 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.404 2008/01/22 21:30:53 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
** Change the size of the pager hash table to N.  N must be a power
** of two.
*/
static void pager_resize_hash_table(Pager *pPager, int N){
  PgHdr **aHash, *pPg;
  assert( N>0 && (N&(N-1))==0 );
  pagerLeave(pPager);
  sqlite3MallocBenignFailure((int)pPager->aHash);
  aHash = sqlite3MallocZero( sizeof(aHash[0])*N );

  pagerEnter(pPager);
  if( aHash==0 ){
    /* Failure to rehash is not an error.  It is only a performance hit. */
    return;
  }
  sqlite3_free(pPager->aHash);
  pPager->nHash = N;







|

>







695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
** Change the size of the pager hash table to N.  N must be a power
** of two.
*/
static void pager_resize_hash_table(Pager *pPager, int N){
  PgHdr **aHash, *pPg;
  assert( N>0 && (N&(N-1))==0 );
  pagerLeave(pPager);
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, pPager->aHash!=0);
  aHash = sqlite3MallocZero( sizeof(aHash[0])*N );
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0);
  pagerEnter(pPager);
  if( aHash==0 ){
    /* Failure to rehash is not an error.  It is only a performance hit. */
    return;
  }
  sqlite3_free(pPager->aHash);
  pPager->nHash = N;
Changes to src/sqliteInt.h.
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.652 2008/01/18 14:08:24 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds













|







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.653 2008/01/22 21:30:53 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif

/*
** The MallocDisallow() and MallocAllow() routines are like asserts.
** Call them around a section of code that you do not expect to do
** any memory allocation.
*/
#ifdef SQLITE_MEMDEBUG
  void sqlite3MallocDisallow(void);
  void sqlite3MallocAllow(void);
  void sqlite3MallocBenignFailure(int);
  void sqlite3MallocEnterBenignBlock(int isBenign);
  void sqlite3MallocLeaveBenignBlock();
#else
# define sqlite3MallocDisallow()
# define sqlite3MallocAllow()
# define sqlite3MallocBenignFailure(x)
# define sqlite3MallocEnterBenignBlock(x);
# define sqlite3MallocLeaveBenignBlock();
#endif


#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(X)
#  define sqlite3VtabSync(X,Y) (Y)
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#else







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1971
1972
1973
1974
1975
1976
1977




















1978
1979
1980
1981
1982
1983
1984
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif





















#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(X)
#  define sqlite3VtabSync(X,Y) (Y)
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#else
2019
2020
2021
2022
2023
2024
2025































2026
2027
2028
2029
2030
2031
2032
int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
































#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX           3
int sqlite3FindInIndex(Parse *, Expr *, int);

#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);







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







1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);


/*
** Available fault injectors.  Should be numbered beginning with 0.
*/
#define SQLITE_FAULTINJECTOR_MALLOC     0
#define SQLITE_FAULTINJECTOR_SAFETY     1
#define SQLITE_FAULTINJECTOR_COUNT      2

/*
** The interface to the fault injector subsystem.  If the fault injector
** mechanism is disabled at compile-time then set up macros so that no
** unnecessary code is generated.
*/
#ifndef SQLITE_OMIT_FAULTINJECTOR
  void sqlite3FaultConfig(int,int,int);
  int sqlite3FaultFailures(int);
  int sqlite3FaultBenignFailures(int);
  int sqlite3FaultPending(int);
  void sqlite3FaultBenign(int,int);
  int sqlite3FaultStep(int);
#else
# define sqlite3FaultConfig(A,B,C)
# define sqlite3FaultFailures(A)         0
# define sqlite3FaultBenignFailures(A)   0
# define sqlite3FaultPending(A)          (-1)
# define sqlite3FaultBenign(A,B)
# define sqlite3FaultStep(A)             0
#endif
  
  

#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX           3
int sqlite3FindInIndex(Parse *, Expr *, int);

#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
Changes to src/test1.c.
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 all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.285 2008/01/22 14:50:17 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*







|







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 all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.286 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
    sqlite3_soft_heap_limit(N);
    softHeapLimit = N;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
  return TCL_OK;
}

/*
** Usage:   sqlite3_clear_tsd_memdebug
**
** Clear all of the MEMDEBUG information out of thread-specific data.
** This will allow it to be deallocated.
*/
static int test_clear_tsd_memdebug(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  return TCL_OK;
}

/*
** Usage:   sqlite3_tsd_release
**
** Call sqlite3ReleaseThreadData.
*/
static int test_tsd_release(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  return TCL_OK;
}

/*
** Usage:   sqlite3_thread_cleanup
**
** Call the sqlite3_thread_cleanup API.
*/
static int test_thread_cleanup(
  void * clientData,







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







4091
4092
4093
4094
4095
4096
4097





























4098
4099
4100
4101
4102
4103
4104
    sqlite3_soft_heap_limit(N);
    softHeapLimit = N;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
  return TCL_OK;
}






























/*
** Usage:   sqlite3_thread_cleanup
**
** Call the sqlite3_thread_cleanup API.
*/
static int test_thread_cleanup(
  void * clientData,
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_clear_tsd_memdebug",    test_clear_tsd_memdebug, 0},
     { "sqlite3_tsd_release",           test_tsd_release,        0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},
     { "sqlite3_enable_load_extension", test_enable_load,        0},
     { "sqlite3_extended_result_codes", test_extended_result_codes, 0},








<
<







4436
4437
4438
4439
4440
4441
4442


4443
4444
4445
4446
4447
4448
4449
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},


     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},
     { "sqlite3_enable_load_extension", test_enable_load,        0},
     { "sqlite3_extended_result_codes", test_extended_result_codes, 0},

Changes to src/test8.c.
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 virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.58 2007/12/13 21:54:11 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE







|







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 virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.59 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
1017
1018
1019
1020
1021
1022
1023

1024
1025


1026
1027
1028
1029
1030
1031
1032
    if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){
      rc = -1;
    }
  }
  return rc;
}
static int echoCommit(sqlite3_vtab *tab){

  sqlite3MallocBenignFailure(1);
  return echoTransactionCall(tab, "xCommit");


}
static int echoRollback(sqlite3_vtab *tab){
  return echoTransactionCall(tab, "xRollback");
}

/*
** Implementation of "GLOB" function on the echo module.  Pass







>
|
|
>
>







1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
    if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){
      rc = -1;
    }
  }
  return rc;
}
static int echoCommit(sqlite3_vtab *tab){
  int rc;
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 1);
  rc = echoTransactionCall(tab, "xCommit");
  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0);
  return rc;
}
static int echoRollback(sqlite3_vtab *tab){
  return echoTransactionCall(tab, "xRollback");
}

/*
** Implementation of "GLOB" function on the echo module.  Pass
Changes to src/test_config.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.16 2007/10/19 17:47:25 drh Exp $
*/

#include "sqliteLimit.h"

int sqlite3MAX_LENGTH = SQLITE_MAX_LENGTH;
int sqlite3MAX_COLUMN = SQLITE_MAX_COLUMN;
int sqlite3MAX_SQL_LENGTH = SQLITE_MAX_SQL_LENGTH;







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.17 2008/01/22 21:30:53 drh Exp $
*/

#include "sqliteLimit.h"

int sqlite3MAX_LENGTH = SQLITE_MAX_LENGTH;
int sqlite3MAX_COLUMN = SQLITE_MAX_COLUMN;
int sqlite3MAX_SQL_LENGTH = SQLITE_MAX_SQL_LENGTH;
200
201
202
203
204
205
206






207
208
209
210
211
212
213
#endif

#ifdef SQLITE_OMIT_EXPLAIN
  Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_FLOATING_POINT
  Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY);
#endif








>
>
>
>
>
>







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#endif

#ifdef SQLITE_OMIT_EXPLAIN
  Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_FAULTINJECTOR
  Tcl_SetVar2(interp, "sqlite_options", "faultinjector", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "faultinjector", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_FLOATING_POINT
  Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY);
#endif

Changes to src/test_malloc.c.
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.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.9 2007/10/19 17:47:25 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>








|







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.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.10 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429


/*
** Usage:    sqlite3_memdebug_fail  COUNTER  ?OPTIONS?
**
** where options are:
**
**     -repeat    <boolean>
**     -benigncnt <varname>
**
** Arrange for a simulated malloc() failure after COUNTER successes.
** If REPEAT is 1 then all subsequent malloc()s fail.   If REPEAT is
** 0 then only a single failure occurs.
**
** Each call to this routine overrides the prior counter value.
** This routine returns the number of simulated failures that have
** happened since the previous call to this routine.
**
** To disable simulated failures, use a COUNTER of -1.
*/
static int test_memdebug_fail(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int ii;
  int iFail;
  int iRepeat = -1;
  Tcl_Obj *pBenignCnt = 0;

  int nFail = 0;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;

  for(ii=2; ii<objc; ii+=2){
    int nOption;
    char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption);
    char *zErr = 0;

    if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){
      if( ii==(objc-1) ){
        zErr = "option requires an argument: ";
      }else{
        if( Tcl_GetIntFromObj(interp, objv[ii+1], &iRepeat) ){
          return TCL_ERROR;
        }
      }
    }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){
      if( ii==(objc-1) ){
        zErr = "option requires an argument: ";
      }else{
        pBenignCnt = objv[ii+1];
      }
    }else{
      zErr = "unknown option: ";
    }

    if( zErr ){
      Tcl_AppendResult(interp, zErr, zOption, 0);
      return TCL_ERROR;
    }
  }
  
#ifdef SQLITE_MEMDEBUG
  {
    extern int sqlite3_memdebug_fail(int,int,int*);
    int iBenignCnt;
    nFail = sqlite3_memdebug_fail(iFail, iRepeat, &iBenignCnt);

    if( pBenignCnt ){
      Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(iBenignCnt), 0);
    }
  }
#endif
  Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail));
  return TCL_OK;
}

/*
** Usage:    sqlite3_memdebug_pending
**







|



|
|















|

|

















|



















|
<
<
<
|
>
|
|
|
<
<







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413



414
415
416
417
418


419
420
421
422
423
424
425


/*
** Usage:    sqlite3_memdebug_fail  COUNTER  ?OPTIONS?
**
** where options are:
**
**     -repeat    <count>
**     -benigncnt <varname>
**
** Arrange for a simulated malloc() failure after COUNTER successes.
** If a repeat count is specified, the fault is repeated that many
** times.
**
** Each call to this routine overrides the prior counter value.
** This routine returns the number of simulated failures that have
** happened since the previous call to this routine.
**
** To disable simulated failures, use a COUNTER of -1.
*/
static int test_memdebug_fail(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int ii;
  int iFail;
  int nRepeat = 1;
  Tcl_Obj *pBenignCnt = 0;
  int nBenign;
  int nFail = 0;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;

  for(ii=2; ii<objc; ii+=2){
    int nOption;
    char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption);
    char *zErr = 0;

    if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){
      if( ii==(objc-1) ){
        zErr = "option requires an argument: ";
      }else{
        if( Tcl_GetIntFromObj(interp, objv[ii+1], &nRepeat) ){
          return TCL_ERROR;
        }
      }
    }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){
      if( ii==(objc-1) ){
        zErr = "option requires an argument: ";
      }else{
        pBenignCnt = objv[ii+1];
      }
    }else{
      zErr = "unknown option: ";
    }

    if( zErr ){
      Tcl_AppendResult(interp, zErr, zOption, 0);
      return TCL_ERROR;
    }
  }
  
  nBenign = sqlite3FaultBenignFailures(SQLITE_FAULTINJECTOR_MALLOC);



  nFail = sqlite3FaultFailures(SQLITE_FAULTINJECTOR_MALLOC);
  sqlite3FaultConfig(SQLITE_FAULTINJECTOR_MALLOC, iFail, nRepeat);
  if( pBenignCnt ){
    Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0);
  }


  Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail));
  return TCL_OK;
}

/*
** Usage:    sqlite3_memdebug_pending
**
440
441
442
443
444
445
446
447
448


449
450
451
452
453
454
455
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

#ifdef SQLITE_MEMDEBUG
  {
    extern int sqlite3_memdebug_pending();
    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_pending()));


  }
#endif
  return TCL_OK;
}


/*







<
|
>
>







436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

#ifdef SQLITE_MEMDEBUG
  {

    Tcl_SetObjResult(interp, 
       Tcl_NewIntObj(sqlite3FaultPending(SQLITE_FAULTINJECTOR_MALLOC))
    );
  }
#endif
  return TCL_OK;
}


/*
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** 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.703 2008/01/21 16:22:46 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** 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.704 2008/01/22 21:30:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
  pIn1 = &p->aMem[pOp->p1];
  REGISTER_TRACE(pOp->p1, pIn1);
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){
    rc = sqlite3VdbeMemMove(pOut, pIn1);
  }else{
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);







|







944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
  pIn1 = &p->aMem[pOp->p1];
  REGISTER_TRACE(pOp->p1, pIn1);
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){
    sqlite3VdbeMemMove(pOut, pIn1);
  }else{
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);
Changes to src/vdbeInt.h.
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemTooBig(Mem*);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
int sqlite3VdbeMemMove(Mem*, Mem*);
int sqlite3VdbeMemNulTerminate(Mem*);
int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64);
void sqlite3VdbeMemSetDouble(Mem*, double);
void sqlite3VdbeMemSetNull(Mem*);
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
int sqlite3VdbeMemMakeWriteable(Mem*);







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemTooBig(Mem*);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
void sqlite3VdbeMemMove(Mem*, Mem*);
int sqlite3VdbeMemNulTerminate(Mem*);
int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64);
void sqlite3VdbeMemSetDouble(Mem*, double);
void sqlite3VdbeMemSetNull(Mem*);
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
int sqlite3VdbeMemMakeWriteable(Mem*);
Changes to src/vdbeapi.c.
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
    return SQLITE_MISUSE;
  }
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  sqlite3_mutex_enter(pTo->db->mutex);
  for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
    sqlite3MallocDisallow();
    rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
    sqlite3MallocAllow();
  }
  sqlite3_mutex_leave(pTo->db->mutex);
  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
  return rc;
}

/*







<
|
<







1037
1038
1039
1040
1041
1042
1043

1044

1045
1046
1047
1048
1049
1050
1051
    return SQLITE_MISUSE;
  }
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  sqlite3_mutex_enter(pTo->db->mutex);
  for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){

    sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);

  }
  sqlite3_mutex_leave(pTo->db->mutex);
  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
  return rc;
}

/*
Changes to src/vdbemem.c.
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  return rc;
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.  SQLITE_NOMEM
** might be returned if pFrom held ephemeral data and we were unable
** to allocate enough space to make a copy.
*/
int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
  int rc;
  assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
  assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
  assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  memcpy(pTo, pFrom, sizeof(Mem));
  if( pFrom->flags & MEM_Short ){
    pTo->z = pTo->zShort;
  }
  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;
  if( 0 /* pTo->flags & MEM_Ephem */ ){
    rc = sqlite3VdbeMemMakeWriteable(pTo);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(
  Mem *pMem,          /* Memory cell to set to string value */







|
<
<

|
<












<
<
<
<
<
<







538
539
540
541
542
543
544
545


546
547

548
549
550
551
552
553
554
555
556
557
558
559






560
561
562
563
564
565
566
  return rc;
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.


*/
void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){

  assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
  assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
  assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  memcpy(pTo, pFrom, sizeof(Mem));
  if( pFrom->flags & MEM_Short ){
    pTo->z = pTo->zShort;
  }
  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;






}

/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(
  Mem *pMem,          /* Memory cell to set to string value */
Changes to test/malloc_common.tcl.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.11 2008/01/18 17:03:33 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable !memdebug {
  return 0
}








|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.12 2008/01/22 21:30:53 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable !memdebug {
  return 0
}

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  if {[info exists ::mallocopts(-end)]} {
    set end $::mallocopts(-end)
  } else {
    set end 50000
  }
  save_prng_state

  foreach ::iRepeat {0 1} {
    set ::go 1
    for {set ::n $start} {$::go && $::n <= $end} {incr ::n} {

      # If $::iRepeat is 0, then the malloc() failure is transient - it
      # fails and then subsequent calls succeed. If $::iRepeat is 1, 
      # then the failure is persistent - once malloc() fails it keeps
      # failing.







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  if {[info exists ::mallocopts(-end)]} {
    set end $::mallocopts(-end)
  } else {
    set end 50000
  }
  save_prng_state

  foreach ::iRepeat {0 10000000} {
    set ::go 1
    for {set ::n $start} {$::go && $::n <= $end} {incr ::n} {

      # If $::iRepeat is 0, then the malloc() failure is transient - it
      # fails and then subsequent calls succeed. If $::iRepeat is 1, 
      # then the failure is persistent - once malloc() fails it keeps
      # failing.
121
122
123
124
125
126
127

128
129
130
131
132
133
134
        #
        #     isFail  - True if an error (any error) was reported by sqlite.
        #     nFail   - The total number of simulated malloc() failures.
        #     nBenign - The number of benign simulated malloc() failures.
        #
        set isFail [catch $::mallocbody msg]
        set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]


        # If one or more mallocs failed, run this loop body again.
        #
        set go [expr {$nFail>0}]

        if {($nFail-$nBenign)==0} {
          if {$isFail} {







>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        #
        #     isFail  - True if an error (any error) was reported by sqlite.
        #     nFail   - The total number of simulated malloc() failures.
        #     nBenign - The number of benign simulated malloc() failures.
        #
        set isFail [catch $::mallocbody msg]
        set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]
        # puts -nonewline " (isFail=$isFail nFail=$nFail nBenign=$nBenign) "

        # If one or more mallocs failed, run this loop body again.
        #
        set go [expr {$nFail>0}]

        if {($nFail-$nBenign)==0} {
          if {$isFail} {
Changes to tool/mksqlite3c.tcl.
197
198
199
200
201
202
203

204
205
206
207
208
209
210
#
foreach file {
   sqliteInt.h

   date.c
   os.c


   mem1.c
   mem2.c
   mem3.c
   mutex.c
   mutex_os2.c
   mutex_unix.c
   mutex_w32.c







>







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#
foreach file {
   sqliteInt.h

   date.c
   os.c

   fault.c
   mem1.c
   mem2.c
   mem3.c
   mutex.c
   mutex_os2.c
   mutex_unix.c
   mutex_w32.c