15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2007 August 15 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)************************************************************************* 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains code used to implement test interfaces to the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** memory allocation subsystem. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This structure is used to encapsulate the global state variables used 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by malloc() fault simulation. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct MemFault { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCountdown; /* Number of pending successes before a failure */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRepeat; /* Number of times to repeat the failure */ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBenign; /* Number of benign failures seen since last config */ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nFail; /* Number of failures seen since last config */ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 enable; /* True if enabled */ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isInstalled; /* True if the fault simulation layer is installed */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isBenignMode; /* True if malloc failures are considered benign */ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_mem_methods m; /* 'Real' malloc implementation */ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} memfault; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine exists as a place to set a breakpoint that will 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fire on any simulated malloc() failure. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void sqlite3Fault(void){ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int cnt = 0; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt++; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check to see if a fault should be simulated. Return true to simulate 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the fault. Return false if the fault should not be simulated. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimStep(void){ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( likely(!memfault.enable) ){ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memfault.iCountdown>0 ){ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.iCountdown--; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3Fault(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nFail++; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memfault.isBenignMode>0 ){ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nBenign++; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nRepeat--; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memfault.nRepeat<=0 ){ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.enable = 0; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** logic. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *faultsimMalloc(int n){ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *p = 0; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !faultsimStep() ){ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = memfault.m.xMalloc(n); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** logic. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *faultsimRealloc(void *pOld, int n){ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *p = 0; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !faultsimStep() ){ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = memfault.m.xRealloc(pOld, n); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following method calls are passed directly through to the underlying 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** malloc system: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xFree 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xSize 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xRoundup 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xInit 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xShutdown 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimFree(void *p){ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.m.xFree(p); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimSize(void *p){ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.m.xSize(p); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimRoundup(int n){ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.m.xRoundup(n); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimInit(void *p){ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.m.xInit(memfault.m.pAppData); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimShutdown(void *p){ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.m.xShutdown(memfault.m.pAppData); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine configures the malloc failure simulation. After 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** calling this routine, the next nDelay mallocs will succeed, followed 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by a block of nRepeat failures, after which malloc() calls will begin 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to succeed again. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimConfig(int nDelay, int nRepeat){ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.iCountdown = nDelay; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nRepeat = nRepeat; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nBenign = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.nFail = 0; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.enable = nDelay>=0; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sometimes, when running multi-threaded tests, the isBenignMode 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** variable is not properly incremented/decremented so that it is 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 0 when not inside a benign malloc block. This doesn't affect 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the multi-threaded tests, as they do not use this system. But 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** it does affect OOM tests run later in the same process. So 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** zero the variable here, just to be sure. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.isBenignMode = 0; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of faults (both hard and benign faults) that have 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** occurred since the injector was last configured. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimFailures(void){ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.nFail; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of benign faults that have occurred since the 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** injector was last configured. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimBenignFailures(void){ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.nBenign; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of successes that will occur before the next failure. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If no failures are scheduled, return -1. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimPending(void){ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memfault.enable ){ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memfault.iCountdown; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimBeginBenign(void){ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.isBenignMode++; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimEndBenign(void){ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.isBenignMode--; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add or remove the fault-simulation layer using sqlite3_config(). If 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the argument is non-zero, the 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimInstall(int install){ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct sqlite3_mem_methods m = { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimMalloc, /* xMalloc */ 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimFree, /* xFree */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimRealloc, /* xRealloc */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimSize, /* xSize */ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimRoundup, /* xRoundup */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimInit, /* xInit */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimShutdown, /* xShutdown */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /* pAppData */ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install = (install ? 1 : 0); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(memfault.isInstalled==1 || memfault.isInstalled==0); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( install==memfault.isInstalled ){ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_ERROR; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( install ){ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(memfault.m.xMalloc); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimBeginBenign, faultsimEndBenign 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_mem_methods m; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(memfault.m.xMalloc); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* One should be able to reset the default memory allocator by storing 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a zeroed allocator then calling GETMALLOC. */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&m, 0, sizeof(m)); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_config(SQLITE_CONFIG_MALLOC, &m); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( memcmp(&m, &memfault.m, sizeof(m))==0 ); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memfault.isInstalled = 1; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is implemented in test1.c. Returns a pointer to a static 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffer containing the symbolic SQLite error code that corresponds to 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the least-significant 8-bits of the integer passed as an argument. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For example: 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3TestErrorName(1) -> "SQLITE_ERROR" 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *sqlite3TestErrorName(int); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Transform pointers to text and back again 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void pointerToText(void *p, char *z){ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char zHex[] = "0123456789abcdef"; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, k; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int u; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 n; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p==0 ){ 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(z, "0"); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sizeof(n)==sizeof(p) ){ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&n, &p, sizeof(p)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( sizeof(u)==sizeof(p) ){ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&u, &p, sizeof(u)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = u; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( 0 ); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[k] = zHex[n&0xf]; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n >>= 4; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[sizeof(p)*2] = 0; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int hexToInt(int h){ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( h>='0' && h<='9' ){ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h - '0'; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( h>='a' && h<='f' ){ 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h - 'a' + 10; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int textToPointer(const char *z, void **pp){ 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 n = 0; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int u; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sizeof(void*)*2 && z[0]; i++){ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int v; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = hexToInt(*z++); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( v<0 ) return TCL_ERROR; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = n*16 + v; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *z!=0 ) return TCL_ERROR; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sizeof(n)==sizeof(*pp) ){ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pp, &n, sizeof(n)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( sizeof(u)==sizeof(*pp) ){ 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u = (unsigned int)n; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pp, &u, sizeof(u)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( 0 ); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_malloc NBYTES 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_malloc(). 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_malloc( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *p; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zOut[100]; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "NBYTES"); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &nByte) ) return TCL_ERROR; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = sqlite3_malloc((unsigned)nByte); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointerToText(p, zOut); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zOut, NULL); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_realloc PRIOR NBYTES 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_realloc(). 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_realloc( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *pPrior, *p; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zOut[100]; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES"); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &nByte) ) return TCL_ERROR; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){ 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = sqlite3_realloc(pPrior, (unsigned)nByte); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointerToText(p, zOut); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zOut, NULL); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_free PRIOR 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_free(). 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_free( 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *pPrior; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "PRIOR"); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){ 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pPrior); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These routines are in test_hexio.c 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3TestHexToBin(const char *, int, char *); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3TestBinToHex(char*,int); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: memset ADDRESS SIZE HEX 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set a chunk of memory (obtained from malloc, probably) to a 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** specified hex pattern. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memset( 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *p; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size, n, i; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zHex; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zOut; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zBin[100]; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=4 ){ 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX"); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( textToPointer(Tcl_GetString(objv[1]), &p) ){ 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &size) ){ 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( size<=0 ){ 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "size must be positive", (char*)0); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zHex = Tcl_GetStringFromObj(objv[3], &n); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = sqlite3TestHexToBin(zHex, n, zBin); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n==0 ){ 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no data", (char*)0); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOut = p; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++){ 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOut[i] = zBin[i%n]; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: memget ADDRESS SIZE 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return memory as hexadecimal text. 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memget( 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *p; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size, n; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zBin; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zHex[100]; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE"); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( textToPointer(Tcl_GetString(objv[1]), &p) ){ 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &size) ){ 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( size<=0 ){ 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "size must be positive", (char*)0); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBin = p; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( size>0 ){ 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( size>(sizeof(zHex)-1)/2 ){ 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = (sizeof(zHex)-1)/2; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = size; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(zHex, zBin, n); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBin += n; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size -= n; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3TestBinToHex(zHex, n); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zHex, (char*)0); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memory_used 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_memory_used(). 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memory_used( 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_memory_used())); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memory_highwater ?RESETFLAG? 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_memory_highwater(). 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memory_highwater( 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resetFlag = 0; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=1 && objc!=2 ){ 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "?RESET?"); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc==2 ){ 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetBooleanFromObj(interp, objv[1], &resetFlag) ) return TCL_ERROR; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_NewWideIntObj(sqlite3_memory_highwater(resetFlag))); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_backtrace DEPTH 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the depth of backtracing. If SQLITE_MEMDEBUG is not defined 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then this routine is a no-op. 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_backtrace( 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int depth; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "DEPT"); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &depth) ) return TCL_ERROR; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3MemdebugBacktrace(int); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3MemdebugBacktrace(depth); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_dump FILENAME 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write a summary of unfreed memory to FILENAME. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_dump( 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_MEMDEBUG) || defined(SQLITE_MEMORY_SIZE) \ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || defined(SQLITE_POW2_MEMORY_SIZE) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3MemdebugDump(const char*); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3MemdebugDump(Tcl_GetString(objv[1])); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_malloc_count 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the total number of times malloc() has been called. 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_malloc_count( 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nMalloc = -1; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=1 ){ 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, ""); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_MEMDEBUG) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3MemdebugMallocCount(); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nMalloc = sqlite3MemdebugMallocCount(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(nMalloc)); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS? 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** where options are: 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** -repeat <count> 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** -benigncnt <varname> 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Arrange for a simulated malloc() failure after COUNTER successes. 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If a repeat count is specified, the fault is repeated that many 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** times. 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each call to this routine overrides the prior counter value. 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine returns the number of simulated failures that have 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** happened since the previous call to this routine. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To disable simulated failures, use a COUNTER of -1. 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_fail( 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ii; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFail; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRepeat = 1; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pBenignCnt = 0; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBenign; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nFail = 0; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc<2 ){ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?"); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ii=2; ii<objc; ii+=2){ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOption; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zErr = 0; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){ 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ii==(objc-1) ){ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zErr = "option requires an argument: "; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[ii+1], &nRepeat) ){ 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){ 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ii==(objc-1) ){ 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zErr = "option requires an argument: "; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBenignCnt = objv[ii+1]; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zErr = "unknown option: "; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zErr ){ 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zErr, zOption, 0); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nBenign = faultsimBenignFailures(); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nFail = faultsimFailures(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) faultsimConfig(iFail, nRepeat); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pBenignCnt ){ 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail)); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_pending 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of malloc() calls that will succeed before a 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** simulated failure occurs. A negative return value indicates that 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no malloc() failure is scheduled. 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_pending( 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nPending; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=1 ){ 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, ""); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nPending = faultsimPending(); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(nPending)); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_memdebug_settitle TITLE 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set a title string stored with each allocation. The TITLE is 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** typically the name of the test that was running when the 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allocation occurred. The TITLE is stored with the allocation 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and can be used to figure out which tests are leaking memory. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each title overwrite the previous. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_settitle( 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zTitle; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "TITLE"); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zTitle = Tcl_GetString(objv[1]); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3MemdebugSettitle(const char*); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3MemdebugSettitle(zTitle); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MALLOC_LOG_FRAMES 10 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MALLOC_LOG_KEYINTS ( \ 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int)) \ 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Tcl_HashTable aMallocLog; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int mallocLogEnabled = 0; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct MallocLog MallocLog; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MallocLog { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nCall; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){ 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mallocLogEnabled ){ 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MallocLog *pLog; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_HashEntry *pEntry; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isNew; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int aKey[MALLOC_LOG_KEYINTS]; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nKey = sizeof(int)*MALLOC_LOG_KEYINTS; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(aKey, 0, nKey); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (sizeof(void*)*nFrame)<nKey ){ 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nKey = nFrame*sizeof(void*); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(aKey, aFrame, nKey); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry = Tcl_CreateHashEntry(&aMallocLog, (const char *)aKey, &isNew); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isNew ){ 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLog = (MallocLog *)Tcl_Alloc(sizeof(MallocLog)); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pLog, 0, sizeof(MallocLog)); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetHashValue(pEntry, (ClientData)pLog); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLog = (MallocLog *)Tcl_GetHashValue(pEntry); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLog->nCall++; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLog->nByte += nByte; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_MEMDEBUG */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_memdebug_log_clear(void){ 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_HashSearch search; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_HashEntry *pEntry; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry=Tcl_FirstHashEntry(&aMallocLog, &search); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry=Tcl_NextHashEntry(&search) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Free((char *)pLog); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_DeleteHashTable(&aMallocLog); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_log( 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int isInit = 0; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iSub; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char *MB_strs[] = { "start", "stop", "dump", "clear", "sync" }; 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum MB_enum { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR, MB_LOG_SYNC 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !isInit ){ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3MemdebugBacktraceCallback( 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*xBacktrace)(int, int, void **)); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3MemdebugBacktraceCallback(test_memdebug_callback); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isInit = 1; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc<2 ){ 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, &iSub) ){ 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( (enum MB_enum)iSub ){ 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MB_LOG_START: 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mallocLogEnabled = 1; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MB_LOG_STOP: 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mallocLogEnabled = 0; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MB_LOG_DUMP: { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_HashSearch search; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_HashEntry *pEntry; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pRet = Tcl_NewObj(); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(sizeof(Tcl_WideInt)>=sizeof(void*)); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry=Tcl_FirstHashEntry(&aMallocLog, &search); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEntry=Tcl_NextHashEntry(&search) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2]; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ii; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apElem[0] = Tcl_NewIntObj(pLog->nCall); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apElem[1] = Tcl_NewIntObj(pLog->nByte); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(interp, pRet, 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pRet); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MB_LOG_CLEAR: { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_memdebug_log_clear(); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MB_LOG_SYNC: { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3MemdebugSync(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_memdebug_log_clear(); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mallocLogEnabled = 1; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3MemdebugSync(); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_config_scratch SIZE N 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH. 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The buffer is static and is of limited size. N might be 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** adjusted downward as needed to accomodate the requested size. 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The revised value of N is returned. 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A negative SIZE causes the buffer pointer to be NULL. 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_scratch( 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sz, N, rc; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pResult; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char *buf = 0; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "SIZE N"); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(buf); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sz<0 ){ 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = 0; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = malloc( sz*N + 1 ); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pResult = Tcl_NewObj(); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N)); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pResult); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_config_pagecache SIZE N 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE. 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The buffer is static and is of limited size. N might be 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** adjusted downward as needed to accomodate the requested size. 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The revised value of N is returned. 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A negative SIZE causes the buffer pointer to be NULL. 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_pagecache( 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sz, N, rc; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pResult; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char *buf = 0; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "SIZE N"); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(buf); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sz<0 ){ 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = 0; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = malloc( sz*N ); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pResult = Tcl_NewObj(); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N)); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pResult); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_config_alt_pcache INSTALL_FLAG DISCARD_CHANCE PRNG_SEED 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set up the alternative test page cache. Install if INSTALL_FLAG is 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** true and uninstall (reverting to the default page cache) if INSTALL_FLAG 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is false. DISCARD_CHANGE is an integer between 0 and 100 inclusive 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** which determines the chance of discarding a page when unpinned. 100 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is certainty. 0 is never. PRNG_SEED is the pseudo-random number generator 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** seed. 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_alt_pcache( 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int installFlag; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int discardChance = 0; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prngSeed = 0; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int highStress = 0; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void installTestPCache(int,unsigned,unsigned,unsigned); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc<2 || objc>5 ){ 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSTALLFLAG DISCARDCHANCE PRNGSEEED HIGHSTRESS"); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &installFlag) ) return TCL_ERROR; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc>=3 && Tcl_GetIntFromObj(interp, objv[2], &discardChance) ){ 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc>=4 && Tcl_GetIntFromObj(interp, objv[3], &prngSeed) ){ 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc>=5 && Tcl_GetIntFromObj(interp, objv[4], &highStress) ){ 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( discardChance<0 || discardChance>100 ){ 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "discard-chance should be between 0 and 100", 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*)0); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installTestPCache(installFlag, (unsigned)discardChance, (unsigned)prngSeed, 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned)highStress); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_config_memstatus BOOLEAN 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS. 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_memstatus( 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int enable, rc; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN"); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_MEMSTATUS, enable); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_config_lookaside SIZE COUNT 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_lookaside( 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sz, cnt; 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pRet; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT"); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &cnt) ) return TCL_ERROR; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRet = Tcl_NewObj(); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement( 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.szLookaside) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement( 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.nLookaside) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pRet); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_db_config_lookaside CONNECTION BUFID SIZE COUNT 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There are two static buffers with BUFID 1 and 2. Each static buffer 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is 10KB in size. A BUFID of 0 indicates that the buffer should be NULL 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** which will cause sqlite3_db_config() to allocate space on its own. 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_db_config_lookaside( 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sz, cnt; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bufid; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char azBuf[2][10000]; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int getDbPointer(Tcl_Interp*, const char*, sqlite3**); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=5 ){ 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "BUFID SIZE COUNT"); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &bufid) ) return TCL_ERROR; 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR; 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bufid==0 ){ 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){ 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "illegal arguments - see documentation", (char*)0); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_config_heap NBYTE NMINALLOC 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_heap( 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char *zBuf; /* Use this memory */ 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int szBuf; /* Bytes allocated for zBuf */ 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; /* Size of buffer to pass to sqlite3_config() */ 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nMinAlloc; /* Size of minimum allocation */ 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* Return code of sqlite3_config() */ 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj * CONST *aArg = &objv[1]; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nArg = objc-1; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nArg!=2 ){ 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "NBYTE NMINALLOC"); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, aArg[1], &nMinAlloc) ) return TCL_ERROR; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nByte==0 ){ 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free( zBuf ); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBuf = 0; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) szBuf = 0; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void*)0, 0, 0); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBuf = realloc(zBuf, nByte); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) szBuf = nByte; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tclcmd: sqlite3_config_error [DB] 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Invoke sqlite3_config() or sqlite3_db_config() with invalid 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** opcodes and verify that they return errors. 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_error( 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int getDbPointer(Tcl_Interp*, const char*, sqlite3**); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 && objc!=1 ){ 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "[DB]"); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc==2 ){ 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){ 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR", 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*)0); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3_config(99999)!=SQLITE_ERROR ){ 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sqlite3_config(99999) does not return SQLITE_ERROR", 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*)0); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_dump_memsys3 FILENAME 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_dump_memsys5 FILENAME 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write a summary of unfreed memsys3 allocations to FILENAME. 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_dump_memsys3( 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( (int)clientData ){ 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: { 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS3 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3Memsys3Dump(const char*); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3Memsys3Dump(Tcl_GetString(objv[1])); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: { 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS5 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void sqlite3Memsys5Dump(const char*); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3Memsys5Dump(Tcl_GetString(objv[1])); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_status OPCODE RESETFLAG 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a list of three elements which are the sqlite3_status() return 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code, the current value, and the high-water mark value. 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_status( 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc, iValue, mxValue; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, op, resetFlag; 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zOpName; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const struct { 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName; 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op; 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } aOp[] = { 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED }, 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE }, 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED }, 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW }, 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_PAGECACHE_SIZE", SQLITE_STATUS_PAGECACHE_SIZE }, 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED }, 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW }, 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_SCRATCH_SIZE", SQLITE_STATUS_SCRATCH_SIZE }, 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_PARSER_STACK", SQLITE_STATUS_PARSER_STACK }, 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SQLITE_STATUS_MALLOC_COUNT", SQLITE_STATUS_MALLOC_COUNT }, 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pResult; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG"); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOpName = Tcl_GetString(objv[1]); 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<ArraySize(aOp); i++){ 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(aOp[i].zName, zOpName)==0 ){ 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = aOp[i].op; 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>=ArraySize(aOp) ){ 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR; 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR; 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iValue = 0; 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mxValue = 0; 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_status(op, &iValue, &mxValue, resetFlag); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pResult = Tcl_NewObj(); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue)); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue)); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pResult); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: sqlite3_db_status DATABASE OPCODE RESETFLAG 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a list of three elements which are the sqlite3_db_status() return 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code, the current value, and the high-water mark value. 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_db_status( 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc, iValue, mxValue; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, op, resetFlag; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zOpName; 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int getDbPointer(Tcl_Interp*, const char*, sqlite3**); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const struct { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op; 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } aOp[] = { 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "LOOKASIDE_USED", SQLITE_DBSTATUS_LOOKASIDE_USED }, 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "CACHE_USED", SQLITE_DBSTATUS_CACHE_USED }, 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "SCHEMA_USED", SQLITE_DBSTATUS_SCHEMA_USED }, 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "STMT_USED", SQLITE_DBSTATUS_STMT_USED }, 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT }, 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE }, 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL } 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *pResult; 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=4 ){ 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG"); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOpName = Tcl_GetString(objv[2]); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memcmp(zOpName, "SQLITE_", 7)==0 ) zOpName += 7; 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( memcmp(zOpName, "DBSTATUS_", 9)==0 ) zOpName += 9; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<ArraySize(aOp); i++){ 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(aOp[i].zName, zOpName)==0 ){ 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = aOp[i].op; 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>=ArraySize(aOp) ){ 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR; 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iValue = 0; 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mxValue = 0; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_db_status(db, op, &iValue, &mxValue, resetFlag); 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pResult = Tcl_NewObj(); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue)); 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue)); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, pResult); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** install_malloc_faultsim BOOLEAN 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_install_malloc_faultsim( 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isInstall; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN"); 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){ 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = faultsimInstall(isInstall); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_install_memsys3 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_install_memsys3( 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_MISUSE; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS3 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetMemsys3()); 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_vfs_oom_test( 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * clientData, 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3_memdebug_vfs_oom_test; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc>2 ){ 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "?INTEGER?"); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( objc==2 ){ 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iNew; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIntFromObj(interp, objv[1], &iNew) ) return TCL_ERROR; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_memdebug_vfs_oom_test = iNew; 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_vfs_oom_test)); 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter. 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_malloc_Init(Tcl_Interp *interp){ 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct { 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zName; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ObjCmdProc *xProc; 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int clientData; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } aObjCmd[] = { 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_malloc", test_malloc ,0 }, 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_realloc", test_realloc ,0 }, 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_free", test_free ,0 }, 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "memset", test_memset ,0 }, 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "memget", test_memget ,0 }, 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memory_used", test_memory_used ,0 }, 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memory_highwater", test_memory_highwater ,0 }, 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_backtrace", test_memdebug_backtrace ,0 }, 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_dump", test_memdebug_dump ,0 }, 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_fail", test_memdebug_fail ,0 }, 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_pending", test_memdebug_pending ,0 }, 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 }, 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 }, 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_log", test_memdebug_log ,0 }, 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_scratch", test_config_scratch ,0 }, 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_pagecache", test_config_pagecache ,0 }, 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_alt_pcache", test_alt_pcache ,0 }, 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_status", test_status ,0 }, 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_db_status", test_db_status ,0 }, 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_heap", test_config_heap ,0 }, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_memstatus", test_config_memstatus ,0 }, 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_lookaside", test_config_lookaside ,0 }, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_config_error", test_config_error ,0 }, 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_install_memsys3", test_install_memsys3 ,0 }, 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 }, 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientData c = (ClientData)aObjCmd[i].clientData; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1439