mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix a race condition in sqlite3_initialize(). (CVS 5310)
FossilOrigin-Name: 70b2ed2afcf1757d1c58f3a83dad4a5fb226ae63
This commit is contained in:
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
|||||||
C Documentation\supdates.\s\sNo\schanges\sto\scode.\s(CVS\s5309)
|
C Fix\sa\srace\scondition\sin\ssqlite3_initialize().\s(CVS\s5310)
|
||||||
D 2008-06-26T02:53:02
|
D 2008-06-26T08:29:34
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in dcf0ecf664a31c257f540d32e5d69a09edf962f0
|
F Makefile.in dcf0ecf664a31c257f540d32e5d69a09edf962f0
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -114,7 +114,7 @@ F src/insert.c f8c7da31409ec19a769b960a4a2b9cca7bab80bd
|
|||||||
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
||||||
F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
|
F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
|
||||||
F src/loadext.c 40024a0f476c1279494876b9a002001b29e5d3e3
|
F src/loadext.c 40024a0f476c1279494876b9a002001b29e5d3e3
|
||||||
F src/main.c 88a34d852e8e592b89146d3975b37cea3dd3160d
|
F src/main.c f26f9dd14d04f2d4c7492627dd9ad2f62e5bfe06
|
||||||
F src/malloc.c f52166df8abd7ff6990dbee1a0ce3534addc8617
|
F src/malloc.c f52166df8abd7ff6990dbee1a0ce3534addc8617
|
||||||
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
||||||
F src/mem1.c 8340fa5f969e9f9b9bdeb54106457a2003456d2b
|
F src/mem1.c 8340fa5f969e9f9b9bdeb54106457a2003456d2b
|
||||||
@ -127,7 +127,7 @@ F src/mutex.h 236677b27760d85701b5872d01b5cafedde5f0a9
|
|||||||
F src/mutex_os2.c 9c5637aa4c307c552566d0f0b3bd206245b54a97
|
F src/mutex_os2.c 9c5637aa4c307c552566d0f0b3bd206245b54a97
|
||||||
F src/mutex_unix.c c1526811f4b97a7cd9d4d72d2b9623d06abd05ce
|
F src/mutex_unix.c c1526811f4b97a7cd9d4d72d2b9623d06abd05ce
|
||||||
F src/mutex_w32.c 7aa9ad79b36931314b81ac4045f40f2c503b1e44
|
F src/mutex_w32.c 7aa9ad79b36931314b81ac4045f40f2c503b1e44
|
||||||
F src/os.c 3e98547ef92358a44ed32e025b81599026c2660f
|
F src/os.c a8ef763c0f196c928be23e20ca5d7911bc095318
|
||||||
F src/os.h a7bc8d7232b69ce8ba536cafd8514c877bc3342c
|
F src/os.h a7bc8d7232b69ce8ba536cafd8514c877bc3342c
|
||||||
F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
||||||
F src/os_os2.c 205900770c90f77718dcae4d8f28c60ab4657250
|
F src/os_os2.c 205900770c90f77718dcae4d8f28c60ab4657250
|
||||||
@ -144,7 +144,7 @@ F src/select.c 79f60dc4a7e90bb907c7a2cca42f45276d1ead99
|
|||||||
F src/shell.c 61fa61932ed52825720ebfd3f8381b8d550ef766
|
F src/shell.c 61fa61932ed52825720ebfd3f8381b8d550ef766
|
||||||
F src/sqlite.h.in 0dfa5d11d2c063ef551cbc9f3933295857e420fc
|
F src/sqlite.h.in 0dfa5d11d2c063ef551cbc9f3933295857e420fc
|
||||||
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
|
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
|
||||||
F src/sqliteInt.h 55d1a6c155eaad745d8e4b7f373f5904337fbaf1
|
F src/sqliteInt.h 71e0839f4d4d8bcb59513da8a74d6652f379b145
|
||||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||||
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
|
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
|
||||||
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
||||||
@ -412,7 +412,7 @@ F test/misc5.test 0b68dcb630d44af2dbcdca94dd2b17c8d580f6fa
|
|||||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||||
F test/misc7.test 26e0d948a413bca61ed031159907a03d64647409
|
F test/misc7.test 26e0d948a413bca61ed031159907a03d64647409
|
||||||
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
||||||
F test/mutex1.test f643fe0753daaed30fa233a83e690f0cff9b596e
|
F test/mutex1.test 0fa3f22a23532791e49df796964bb36ed5ecb5b0
|
||||||
F test/nan.test 14c41572ff52dbc740b1c3303dd313a90dc6084c
|
F test/nan.test 14c41572ff52dbc740b1c3303dd313a90dc6084c
|
||||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||||
@ -428,7 +428,7 @@ F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
|||||||
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
||||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
||||||
F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0
|
F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0
|
||||||
F test/quick.test c5e83a241e9adf989a79f83d1ade1c6cc768f68b
|
F test/quick.test 3dba257b9d4e06e1b0199bc1401052f554ab5f14
|
||||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||||
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
||||||
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
||||||
@ -594,7 +594,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 8c65146ea0e77e8e31fffc467806b1edf91fb4db
|
P cdc4e75a9f1e3c79ade92344cf32a4225222d44f
|
||||||
R 8d998f8b6233260e7b79c9834ce4d483
|
R efe6dda44f31dc9f1fb0b947215f7682
|
||||||
U drh
|
U danielk1977
|
||||||
Z 275bbf775c9970112c0cc3209800d9b5
|
Z d08f97cc458894258dd8328a21886eae
|
||||||
|
@ -1 +1 @@
|
|||||||
cdc4e75a9f1e3c79ade92344cf32a4225222d44f
|
70b2ed2afcf1757d1c58f3a83dad4a5fb226ae63
|
65
src/main.c
65
src/main.c
@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.462 2008/06/25 17:19:01 danielk1977 Exp $
|
** $Id: main.c,v 1.463 2008/06/26 08:29:34 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -66,26 +66,56 @@ char *sqlite3_temp_directory = 0;
|
|||||||
** or for the first call after a call to sqlite3_shutdown.
|
** or for the first call after a call to sqlite3_shutdown.
|
||||||
*/
|
*/
|
||||||
int sqlite3_initialize(void){
|
int sqlite3_initialize(void){
|
||||||
|
static int inProgress = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* If SQLite is already initialized, this call is a no-op. */
|
||||||
if( sqlite3Config.isInit ) return SQLITE_OK;
|
if( sqlite3Config.isInit ) return SQLITE_OK;
|
||||||
|
|
||||||
|
/* Make sure the mutex system is initialized. */
|
||||||
rc = sqlite3MutexInit();
|
rc = sqlite3MutexInit();
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
#ifndef SQLITE_MUTEX_NOOP
|
|
||||||
sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
/* Initialize the malloc() system and the recursive pInitMutex mutex.
|
||||||
#endif
|
** This operation is protected by the STATIC_MASTER mutex.
|
||||||
sqlite3_mutex_enter(pMutex);
|
*/
|
||||||
if( sqlite3Config.isInit==0 ){
|
sqlite3_mutex *pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
||||||
sqlite3Config.isInit = 1;
|
sqlite3_mutex_enter(pMaster);
|
||||||
sqlite3StatusReset();
|
if( !sqlite3Config.isMallocInit ){
|
||||||
if( rc==SQLITE_OK ) rc = sqlite3MallocInit();
|
rc = sqlite3MallocInit();
|
||||||
if( rc==SQLITE_OK ) rc = sqlite3_os_init();
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3Config.isInit = 0;
|
sqlite3Config.isMallocInit = 1;
|
||||||
}else{
|
if( !sqlite3Config.pInitMutex ){
|
||||||
sqlite3Config.isInit = 2;
|
sqlite3Config.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
|
||||||
|
if( sqlite3Config.bCoreMutex && !sqlite3Config.pInitMutex ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3_mutex_leave(pMutex);
|
sqlite3_mutex_leave(pMaster);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter the recursive pInitMutex mutex. After doing so, if the
|
||||||
|
** sqlite3Config.isInit flag is true, then some other thread has
|
||||||
|
** finished doing the initialization. If the inProgress flag is
|
||||||
|
** true, then this function is being called recursively from within
|
||||||
|
** the sqlite3_os_init() call below. In either case, exit early.
|
||||||
|
*/
|
||||||
|
sqlite3_mutex_enter(sqlite3Config.pInitMutex);
|
||||||
|
if( sqlite3Config.isInit || inProgress ){
|
||||||
|
sqlite3_mutex_leave(sqlite3Config.pInitMutex);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
sqlite3StatusReset();
|
||||||
|
inProgress = 1;
|
||||||
|
rc = sqlite3_os_init();
|
||||||
|
inProgress = 0;
|
||||||
|
sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0);
|
||||||
|
sqlite3_mutex_leave(sqlite3Config.pInitMutex);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -97,6 +127,9 @@ int sqlite3_initialize(void){
|
|||||||
** routine is not threadsafe. Not by a long shot.
|
** routine is not threadsafe. Not by a long shot.
|
||||||
*/
|
*/
|
||||||
int sqlite3_shutdown(void){
|
int sqlite3_shutdown(void){
|
||||||
|
sqlite3_mutex_free(sqlite3Config.pInitMutex);
|
||||||
|
sqlite3Config.pInitMutex = 0;
|
||||||
|
sqlite3Config.isMallocInit = 0;
|
||||||
sqlite3_os_end();
|
sqlite3_os_end();
|
||||||
sqlite3MallocEnd();
|
sqlite3MallocEnd();
|
||||||
sqlite3MutexEnd();
|
sqlite3MutexEnd();
|
||||||
@ -119,7 +152,7 @@ int sqlite3_config(int op, ...){
|
|||||||
|
|
||||||
/* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
|
/* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
|
||||||
** the SQLite library is in use. */
|
** the SQLite library is in use. */
|
||||||
if( sqlite3Config.isInit==2 ) return SQLITE_MISUSE;
|
if( sqlite3Config.isInit ) return SQLITE_MISUSE;
|
||||||
|
|
||||||
va_start(ap, op);
|
va_start(ap, op);
|
||||||
switch( op ){
|
switch( op ){
|
||||||
|
10
src/os.c
10
src/os.c
@ -13,7 +13,7 @@
|
|||||||
** This file contains OS interface code that is common to all
|
** This file contains OS interface code that is common to all
|
||||||
** architectures.
|
** architectures.
|
||||||
**
|
**
|
||||||
** $Id: os.c,v 1.116 2008/06/25 17:19:01 danielk1977 Exp $
|
** $Id: os.c,v 1.117 2008/06/26 08:29:34 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#define _SQLITE_OS_C_ 1
|
#define _SQLITE_OS_C_ 1
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@ -243,18 +243,12 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
|
|||||||
** true.
|
** true.
|
||||||
*/
|
*/
|
||||||
int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
|
int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
|
||||||
#ifndef SQLITE_MUTEX_NOOP
|
|
||||||
sqlite3_mutex *mutex = 0;
|
sqlite3_mutex *mutex = 0;
|
||||||
#endif
|
|
||||||
#ifndef SQLITE_OMIT_AUTOINIT
|
#ifndef SQLITE_OMIT_AUTOINIT
|
||||||
int rc = sqlite3_initialize();
|
int rc = sqlite3_initialize();
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
#endif
|
#endif
|
||||||
#ifndef SQLITE_MUTEX_NOOP
|
mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
||||||
if( sqlite3Config.isInit!=1 ){
|
|
||||||
mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sqlite3_mutex_enter(mutex);
|
sqlite3_mutex_enter(mutex);
|
||||||
vfsUnlink(pVfs);
|
vfsUnlink(pVfs);
|
||||||
if( makeDflt || vfsList==0 ){
|
if( makeDflt || vfsList==0 ){
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.729 2008/06/25 17:19:01 danielk1977 Exp $
|
** @(#) $Id: sqliteInt.h,v 1.730 2008/06/26 08:29:34 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -1734,12 +1734,6 @@ typedef struct {
|
|||||||
** Structure containing global configuration data for the SQLite library.
|
** Structure containing global configuration data for the SQLite library.
|
||||||
**
|
**
|
||||||
** This structure also contains some state information.
|
** This structure also contains some state information.
|
||||||
**
|
|
||||||
** The Sqlite3Config.isInit variable indicates whether or not
|
|
||||||
** sqlite3_initialize() has already been called or not. Initially, isInit
|
|
||||||
** is 0. While sqlite3_initialize() is running, it is set to 1. After
|
|
||||||
** sqlite3_initialize has successfully run, the Sqlite3Config.isInit variable
|
|
||||||
** is set to 2. Calling sqlite3_shutdown() resets the value to 0.
|
|
||||||
*/
|
*/
|
||||||
struct Sqlite3Config {
|
struct Sqlite3Config {
|
||||||
int bMemstat; /* True to enable memory status */
|
int bMemstat; /* True to enable memory status */
|
||||||
@ -1756,7 +1750,9 @@ struct Sqlite3Config {
|
|||||||
void *pPage; /* Page cache memory */
|
void *pPage; /* Page cache memory */
|
||||||
int szPage; /* Size of each page in pPage[] */
|
int szPage; /* Size of each page in pPage[] */
|
||||||
int nPage; /* Number of pages in pPage[] */
|
int nPage; /* Number of pages in pPage[] */
|
||||||
int isInit; /* Initialization state */
|
int isInit; /* True after initialization has finished */
|
||||||
|
int isMallocInit; /* True after malloc is initialized */
|
||||||
|
sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
#
|
#
|
||||||
# $Id: mutex1.test,v 1.4 2008/06/19 17:54:33 drh Exp $
|
# $Id: mutex1.test,v 1.5 2008/06/26 08:29:35 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -27,8 +27,9 @@ proc mutex_counters {varname} {
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if
|
# Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if
|
||||||
# is called at the wrong time. And that the first time sqlite3_initialize
|
# is called at the wrong time. And that the first time sqlite3_initialize
|
||||||
# is called it obtains the 'static_master' mutex. Subsequent calls are
|
# is called it obtains the 'static_master' mutex 3 times and a recursive
|
||||||
# no-ops that do not require a mutex.
|
# mutex (sqlite3Config.pInitMutex) twice. Subsequent calls are no-ops
|
||||||
|
# that do not require any mutexes.
|
||||||
#
|
#
|
||||||
do_test mutex1-1.0 {
|
do_test mutex1-1.0 {
|
||||||
install_mutex_counters 1
|
install_mutex_counters 1
|
||||||
@ -64,7 +65,7 @@ do_test mutex1-1.6 {
|
|||||||
do_test mutex1-1.7 {
|
do_test mutex1-1.7 {
|
||||||
mutex_counters counters
|
mutex_counters counters
|
||||||
list $counters(total) $counters(static_master)
|
list $counters(total) $counters(static_master)
|
||||||
} {1 1}
|
} {6 3}
|
||||||
|
|
||||||
do_test mutex1-1.8 {
|
do_test mutex1-1.8 {
|
||||||
clear_mutex_counters
|
clear_mutex_counters
|
||||||
@ -96,8 +97,9 @@ ifcapable threadsafe {
|
|||||||
sqlite3_shutdown
|
sqlite3_shutdown
|
||||||
sqlite3_config $mode
|
sqlite3_config $mode
|
||||||
} SQLITE_OK
|
} SQLITE_OK
|
||||||
|
|
||||||
do_test mutex1.2.$mode.2 {
|
do_test mutex1.2.$mode.2 {
|
||||||
|
sqlite3_initialize
|
||||||
clear_mutex_counters
|
clear_mutex_counters
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
catchsql { CREATE TABLE abc(a, b, c) }
|
catchsql { CREATE TABLE abc(a, b, c) }
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: quick.test,v 1.83 2008/06/25 17:54:55 danielk1977 Exp $
|
# $Id: quick.test,v 1.84 2008/06/26 08:29:35 danielk1977 Exp $
|
||||||
|
|
||||||
proc lshift {lvar} {
|
proc lshift {lvar} {
|
||||||
upvar $lvar l
|
upvar $lvar l
|
||||||
@ -42,6 +42,7 @@ set EXCLUDE {
|
|||||||
all.test
|
all.test
|
||||||
async.test
|
async.test
|
||||||
async2.test
|
async2.test
|
||||||
|
async3.test
|
||||||
corrupt.test
|
corrupt.test
|
||||||
crash.test
|
crash.test
|
||||||
crash2.test
|
crash2.test
|
||||||
|
Reference in New Issue
Block a user