1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Improved diagnostics for Bitvec: Add the sqlite3ShowBitvec() routine that

can be called from a debugger (only available with SQLITE_DEBUG).  Add new
output opcodes for sqlite3BitvecBuiltinTest().

FossilOrigin-Name: dea1e37fa67ada6efc1533b449d9eb22338d9e58eec8f89b48c38319c212c8f4
This commit is contained in:
drh
2025-06-10 16:02:29 +00:00
parent f091f423ad
commit 90ba0d4995
5 changed files with 128 additions and 12 deletions

View File

@@ -1,5 +1,5 @@
C Adjustments\sto\sext/misc/fileio.c\sin\san\sattempt\sto\sget\sit\sto\sbuild\susing\smingw. C Improved\sdiagnostics\sfor\sBitvec:\s\sAdd\sthe\ssqlite3ShowBitvec()\sroutine\sthat\ncan\sbe\scalled\sfrom\sa\sdebugger\s(only\savailable\swith\sSQLITE_DEBUG).\s\sAdd\snew\noutput\sopcodes\sfor\ssqlite3BitvecBuiltinTest().
D 2025-06-09T22:38:34.787 D 2025-06-10T16:02:29.157
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -724,7 +724,7 @@ F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9 F src/bitvec.c 248cfe775b6a6040615d59116fc7468de3568caf802a8ecb5fdedbe4b336357f
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
F src/btree.c 53a9c7b243e94c992853d90f1dac0959028433b4b0d27e04409cee04e001b508 F src/btree.c 53a9c7b243e94c992853d90f1dac0959028433b4b0d27e04409cee04e001b508
F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50
@@ -786,11 +786,11 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482
F src/shell.c.in b8d30c7c5423f471b1eeece90f3e893a236ee2a8ac1aa4489cd819d02aaca8f6 F src/shell.c.in 4ae9ff8e8b23d9a309e50d5b5ef2768b9bb18f748ece2acc2641a3c23b71e2b9
F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
F src/sqliteInt.h 0eeb2d363e7994aba3b482d3a9c88248b4d1fdad39cb65ff48621b2ae494a763 F src/sqliteInt.h 5f190640c1939960f993c07d0e626fb2acc40d42ac12b21811dd6c069fb71db4
F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 2eb4e9bf0f2df50324a62fb272a92bbd931b8b4e4b35bac0c05b676c97b61339 P 96b14a3f1193de8f30e9fa704f87558dab8027a218868d32e47688cd5df497b7
R 03f6560dbd24618e624af3e65c53e572 R 18009ba9dff94b8a020eccfe5001a554
U drh U drh
Z 8fc12f4339a0bebdf37b8d0d53295fc6 Z 5261ad27d85df5b5801fdf97adab7f4f
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
96b14a3f1193de8f30e9fa704f87558dab8027a218868d32e47688cd5df497b7 dea1e37fa67ada6efc1533b449d9eb22338d9e58eec8f89b48c38319c212c8f4

View File

@@ -107,6 +107,7 @@ struct Bitvec {
} u; } u;
}; };
/* /*
** Create a new bitmap object able to handle bits between 0 and iSize, ** Create a new bitmap object able to handle bits between 0 and iSize,
** inclusive. Return a pointer to the new object. Return NULL if ** inclusive. Return a pointer to the new object. Return NULL if
@@ -293,6 +294,52 @@ u32 sqlite3BitvecSize(Bitvec *p){
return p->iSize; return p->iSize;
} }
#ifdef SQLITE_DEBUG
/*
** Show the content of a Bitvec option and its children. Indent
** everything by n spaces. Add x to each bitvec value.
**
** From a debugger such as gdb, one can type:
**
** call sqlite3ShowBitvec(p)
**
** For some Bitvec p and see a recursive view of the Bitvec's content.
*/
static void showBitvec(Bitvec *p, int n, unsigned x){
int i;
if( p==0 ){
printf("NULL\n");
return;
}
printf("Bitvec 0x%p iSize=%d", p, p->iSize);
if( p->iSize<=BITVEC_NBIT ){
printf(" bitmap\n");
printf("%*s bits:", n, "");
for(i=1; i<=BITVEC_NBIT; i++){
if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i);
}
printf("\n");
}else if( p->iDivisor==0 ){
printf(" hash with %d entries\n", p->nSet);
printf("%*s bits:", n, "");
for(i=0; i<BITVEC_NINT; i++){
if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]);
}
printf("\n");
}else{
printf(" sub-bitvec with iDivisor=%d\n", p->iDivisor);
for(i=0; i<BITVEC_NPTR; i++){
if( p->u.apSub[i]==0 ) continue;
printf("%*s apSub[%d]=", n, "", i);
showBitvec(p->u.apSub[i], n+4, i*p->iDivisor);
}
}
}
void sqlite3ShowBitvec(Bitvec *p){
showBitvec(p, 0, 0);
}
#endif
#ifndef SQLITE_UNTESTABLE #ifndef SQLITE_UNTESTABLE
/* /*
** Let V[] be an array of unsigned characters sufficient to hold ** Let V[] be an array of unsigned characters sufficient to hold
@@ -304,6 +351,7 @@ u32 sqlite3BitvecSize(Bitvec *p){
#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7))
#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
/* /*
** This routine runs an extensive test of the Bitvec code. ** This routine runs an extensive test of the Bitvec code.
** **
@@ -312,7 +360,7 @@ u32 sqlite3BitvecSize(Bitvec *p){
** by 0, 1, or 3 operands, depending on the opcode. Another ** by 0, 1, or 3 operands, depending on the opcode. Another
** opcode follows immediately after the last operand. ** opcode follows immediately after the last operand.
** **
** There are 6 opcodes numbered from 0 through 5. 0 is the ** There are opcodes numbered starting with 0. 0 is the
** "halt" opcode and causes the test to end. ** "halt" opcode and causes the test to end.
** **
** 0 Halt and return the number of errors ** 0 Halt and return the number of errors
@@ -321,12 +369,16 @@ u32 sqlite3BitvecSize(Bitvec *p){
** 3 N Set N randomly chosen bits ** 3 N Set N randomly chosen bits
** 4 N Clear N randomly chosen bits ** 4 N Clear N randomly chosen bits
** 5 N S X Set N bits from S increment X in array only, not in bitvec ** 5 N S X Set N bits from S increment X in array only, not in bitvec
** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far
** 7 X Show compile-time parameters and the hash of X
** **
** The opcodes 1 through 4 perform set and clear operations are performed ** The opcodes 1 through 4 perform set and clear operations are performed
** on both a Bitvec object and on a linear array of bits obtained from malloc. ** on both a Bitvec object and on a linear array of bits obtained from malloc.
** Opcode 5 works on the linear array only, not on the Bitvec. ** Opcode 5 works on the linear array only, not on the Bitvec.
** Opcode 5 is used to deliberately induce a fault in order to ** Opcode 5 is used to deliberately induce a fault in order to
** confirm that error detection works. ** confirm that error detection works. Opcodes 6 and greater are
** state output opcodes. Opcodes 6 and greater are no-ops unless
** SQLite has been compiled with SQLITE_DEBUG.
** **
** At the conclusion of the test the linear array is compared ** At the conclusion of the test the linear array is compared
** against the Bitvec object. If there are any differences, ** against the Bitvec object. If there are any differences,
@@ -355,6 +407,26 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
/* Run the program */ /* Run the program */
pc = i = 0; pc = i = 0;
while( (op = aOp[pc])!=0 ){ while( (op = aOp[pc])!=0 ){
if( op>=6 ){
#ifdef SQLITE_DEBUG
if( op==6 ){
sqlite3ShowBitvec(pBitvec);
}else if( op==7 ){
unsigned x = (unsigned)aOp[++pc];
printf("BITVEC_SZ = %d (%d by sizeof)\n",
BITVEC_SZ, (int)sizeof(Bitvec));
printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE);
printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM);
printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT);
printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT);
printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH);
printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR);
printf("hash(%u): %u\n", x, (unsigned)BITVEC_HASH(x));
}
#endif
pc++;
continue;
}
switch( op ){ switch( op ){
case 1: case 1:
case 2: case 2:

View File

@@ -11590,7 +11590,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
{"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
/*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
/*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ {"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "SIZE INT-ARRAY"},
{"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
{"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." },
@@ -11928,6 +11928,49 @@ static int do_meta_command(char *zLine, ShellState *p){
} }
sqlite3_test_control(testctrl, &rc2); sqlite3_test_control(testctrl, &rc2);
break; break;
case SQLITE_TESTCTRL_BITVEC_TEST: {
/* Examples:
** .testctrl bitvec_test 100 6,1 -- Show BITVEC constants
** .testctrl bitvec_test 1000 1,12,7,3 -- Simple test
** ---- --------
** size of Bitvec -----^ ^--- aOp array. 0 added at end.
**
** See comments on sqlite3BitvecBuiltinTest() for more information
** about the aOp[] array.
*/
int iSize;
const char *zTestArg;
int nOp;
int ii, jj, x;
int *aOp;
if( nArg!=4 ){
sqlite3_fprintf(stderr,
"ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n"
);
rc = 1;
goto meta_command_exit;
}
isOk = 3;
iSize = (int)integerValue(azArg[2]);
zTestArg = azArg[3];
nOp = (int)strlen(zTestArg)+1;
aOp = malloc( sizeof(int)*(nOp+1) );
shell_check_oom(aOp);
memset(aOp, 0, sizeof(int)*(nOp+1) );
for(ii = jj = x = 0; zTestArg[ii]!=0; ii++){
if( IsDigit(zTestArg[ii]) ){
x = x*10 + zTestArg[ii] - '0';
}else{
aOp[jj++] = x;
x = 0;
}
}
aOp[jj] = x;
x = sqlite3_test_control(testctrl, iSize, aOp);
sqlite3_fprintf(p->out, "result: %d\n", x);
free(aOp);
break;
}
case SQLITE_TESTCTRL_FAULT_INSTALL: { case SQLITE_TESTCTRL_FAULT_INSTALL: {
int kk; int kk;
int bShowHelp = nArg<=2; int bShowHelp = nArg<=2;

View File

@@ -4894,6 +4894,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3ShowWindow(const Window*); void sqlite3ShowWindow(const Window*);
void sqlite3ShowWinFunc(const Window*); void sqlite3ShowWinFunc(const Window*);
#endif #endif
void sqlite3ShowBitvec(Bitvec*);
#endif #endif
void sqlite3SetString(char **, sqlite3*, const char*); void sqlite3SetString(char **, sqlite3*, const char*);