test_malloc.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  1. /*
  2. ** 2007 August 15
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. **
  13. ** This file contains code used to implement test interfaces to the
  14. ** memory allocation subsystem.
  15. */
  16. #include "sqliteInt.h"
  17. #include "tcl.h"
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <assert.h>
  21. /*
  22. ** This structure is used to encapsulate the global state variables used
  23. ** by malloc() fault simulation.
  24. */
  25. static struct MemFault {
  26. int iCountdown; /* Number of pending successes before a failure */
  27. int nRepeat; /* Number of times to repeat the failure */
  28. int nBenign; /* Number of benign failures seen since last config */
  29. int nFail; /* Number of failures seen since last config */
  30. u8 enable; /* True if enabled */
  31. int isInstalled; /* True if the fault simulation layer is installed */
  32. int isBenignMode; /* True if malloc failures are considered benign */
  33. sqlite3_mem_methods m; /* 'Real' malloc implementation */
  34. } memfault;
  35. /*
  36. ** This routine exists as a place to set a breakpoint that will
  37. ** fire on any simulated malloc() failure.
  38. */
  39. static void sqlite3Fault(void){
  40. static int cnt = 0;
  41. cnt++;
  42. }
  43. /*
  44. ** Check to see if a fault should be simulated. Return true to simulate
  45. ** the fault. Return false if the fault should not be simulated.
  46. */
  47. static int faultsimStep(void){
  48. if( likely(!memfault.enable) ){
  49. return 0;
  50. }
  51. if( memfault.iCountdown>0 ){
  52. memfault.iCountdown--;
  53. return 0;
  54. }
  55. sqlite3Fault();
  56. memfault.nFail++;
  57. if( memfault.isBenignMode>0 ){
  58. memfault.nBenign++;
  59. }
  60. memfault.nRepeat--;
  61. if( memfault.nRepeat<=0 ){
  62. memfault.enable = 0;
  63. }
  64. return 1;
  65. }
  66. /*
  67. ** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation
  68. ** logic.
  69. */
  70. static void *faultsimMalloc(int n){
  71. void *p = 0;
  72. if( !faultsimStep() ){
  73. p = memfault.m.xMalloc(n);
  74. }
  75. return p;
  76. }
  77. /*
  78. ** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation
  79. ** logic.
  80. */
  81. static void *faultsimRealloc(void *pOld, int n){
  82. void *p = 0;
  83. if( !faultsimStep() ){
  84. p = memfault.m.xRealloc(pOld, n);
  85. }
  86. return p;
  87. }
  88. /*
  89. ** The following method calls are passed directly through to the underlying
  90. ** malloc system:
  91. **
  92. ** xFree
  93. ** xSize
  94. ** xRoundup
  95. ** xInit
  96. ** xShutdown
  97. */
  98. static void faultsimFree(void *p){
  99. memfault.m.xFree(p);
  100. }
  101. static int faultsimSize(void *p){
  102. return memfault.m.xSize(p);
  103. }
  104. static int faultsimRoundup(int n){
  105. return memfault.m.xRoundup(n);
  106. }
  107. static int faultsimInit(void *p){
  108. return memfault.m.xInit(memfault.m.pAppData);
  109. }
  110. static void faultsimShutdown(void *p){
  111. memfault.m.xShutdown(memfault.m.pAppData);
  112. }
  113. /*
  114. ** This routine configures the malloc failure simulation. After
  115. ** calling this routine, the next nDelay mallocs will succeed, followed
  116. ** by a block of nRepeat failures, after which malloc() calls will begin
  117. ** to succeed again.
  118. */
  119. static void faultsimConfig(int nDelay, int nRepeat){
  120. memfault.iCountdown = nDelay;
  121. memfault.nRepeat = nRepeat;
  122. memfault.nBenign = 0;
  123. memfault.nFail = 0;
  124. memfault.enable = nDelay>=0;
  125. /* Sometimes, when running multi-threaded tests, the isBenignMode
  126. ** variable is not properly incremented/decremented so that it is
  127. ** 0 when not inside a benign malloc block. This doesn't affect
  128. ** the multi-threaded tests, as they do not use this system. But
  129. ** it does affect OOM tests run later in the same process. So
  130. ** zero the variable here, just to be sure.
  131. */
  132. memfault.isBenignMode = 0;
  133. }
  134. /*
  135. ** Return the number of faults (both hard and benign faults) that have
  136. ** occurred since the injector was last configured.
  137. */
  138. static int faultsimFailures(void){
  139. return memfault.nFail;
  140. }
  141. /*
  142. ** Return the number of benign faults that have occurred since the
  143. ** injector was last configured.
  144. */
  145. static int faultsimBenignFailures(void){
  146. return memfault.nBenign;
  147. }
  148. /*
  149. ** Return the number of successes that will occur before the next failure.
  150. ** If no failures are scheduled, return -1.
  151. */
  152. static int faultsimPending(void){
  153. if( memfault.enable ){
  154. return memfault.iCountdown;
  155. }else{
  156. return -1;
  157. }
  158. }
  159. static void faultsimBeginBenign(void){
  160. memfault.isBenignMode++;
  161. }
  162. static void faultsimEndBenign(void){
  163. memfault.isBenignMode--;
  164. }
  165. /*
  166. ** Add or remove the fault-simulation layer using sqlite3_config(). If
  167. ** the argument is non-zero, the
  168. */
  169. static int faultsimInstall(int install){
  170. static struct sqlite3_mem_methods m = {
  171. faultsimMalloc, /* xMalloc */
  172. faultsimFree, /* xFree */
  173. faultsimRealloc, /* xRealloc */
  174. faultsimSize, /* xSize */
  175. faultsimRoundup, /* xRoundup */
  176. faultsimInit, /* xInit */
  177. faultsimShutdown, /* xShutdown */
  178. 0 /* pAppData */
  179. };
  180. int rc;
  181. install = (install ? 1 : 0);
  182. assert(memfault.isInstalled==1 || memfault.isInstalled==0);
  183. if( install==memfault.isInstalled ){
  184. return SQLITE_ERROR;
  185. }
  186. if( install ){
  187. rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
  188. assert(memfault.m.xMalloc);
  189. if( rc==SQLITE_OK ){
  190. rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
  191. }
  192. sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,
  193. faultsimBeginBenign, faultsimEndBenign
  194. );
  195. }else{
  196. sqlite3_mem_methods m;
  197. assert(memfault.m.xMalloc);
  198. /* One should be able to reset the default memory allocator by storing
  199. ** a zeroed allocator then calling GETMALLOC. */
  200. memset(&m, 0, sizeof(m));
  201. sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
  202. sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
  203. assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
  204. rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
  205. sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
  206. }
  207. if( rc==SQLITE_OK ){
  208. memfault.isInstalled = 1;
  209. }
  210. return rc;
  211. }
  212. #ifdef SQLITE_TEST
  213. /*
  214. ** This function is implemented in main.c. Returns a pointer to a static
  215. ** buffer containing the symbolic SQLite error code that corresponds to
  216. ** the least-significant 8-bits of the integer passed as an argument.
  217. ** For example:
  218. **
  219. ** sqlite3ErrName(1) -> "SQLITE_ERROR"
  220. */
  221. extern const char *sqlite3ErrName(int);
  222. /*
  223. ** Transform pointers to text and back again
  224. */
  225. static void pointerToText(void *p, char *z){
  226. static const char zHex[] = "0123456789abcdef";
  227. int i, k;
  228. unsigned int u;
  229. sqlite3_uint64 n;
  230. if( p==0 ){
  231. strcpy(z, "0");
  232. return;
  233. }
  234. if( sizeof(n)==sizeof(p) ){
  235. memcpy(&n, &p, sizeof(p));
  236. }else if( sizeof(u)==sizeof(p) ){
  237. memcpy(&u, &p, sizeof(u));
  238. n = u;
  239. }else{
  240. assert( 0 );
  241. }
  242. for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){
  243. z[k] = zHex[n&0xf];
  244. n >>= 4;
  245. }
  246. z[sizeof(p)*2] = 0;
  247. }
  248. static int hexToInt(int h){
  249. if( h>='0' && h<='9' ){
  250. return h - '0';
  251. }else if( h>='a' && h<='f' ){
  252. return h - 'a' + 10;
  253. }else{
  254. return -1;
  255. }
  256. }
  257. static int textToPointer(const char *z, void **pp){
  258. sqlite3_uint64 n = 0;
  259. int i;
  260. unsigned int u;
  261. for(i=0; i<sizeof(void*)*2 && z[0]; i++){
  262. int v;
  263. v = hexToInt(*z++);
  264. if( v<0 ) return TCL_ERROR;
  265. n = n*16 + v;
  266. }
  267. if( *z!=0 ) return TCL_ERROR;
  268. if( sizeof(n)==sizeof(*pp) ){
  269. memcpy(pp, &n, sizeof(n));
  270. }else if( sizeof(u)==sizeof(*pp) ){
  271. u = (unsigned int)n;
  272. memcpy(pp, &u, sizeof(u));
  273. }else{
  274. assert( 0 );
  275. }
  276. return TCL_OK;
  277. }
  278. /*
  279. ** Usage: sqlite3_malloc NBYTES
  280. **
  281. ** Raw test interface for sqlite3_malloc().
  282. */
  283. static int test_malloc(
  284. void * clientData,
  285. Tcl_Interp *interp,
  286. int objc,
  287. Tcl_Obj *CONST objv[]
  288. ){
  289. int nByte;
  290. void *p;
  291. char zOut[100];
  292. if( objc!=2 ){
  293. Tcl_WrongNumArgs(interp, 1, objv, "NBYTES");
  294. return TCL_ERROR;
  295. }
  296. if( Tcl_GetIntFromObj(interp, objv[1], &nByte) ) return TCL_ERROR;
  297. p = sqlite3_malloc((unsigned)nByte);
  298. pointerToText(p, zOut);
  299. Tcl_AppendResult(interp, zOut, NULL);
  300. return TCL_OK;
  301. }
  302. /*
  303. ** Usage: sqlite3_realloc PRIOR NBYTES
  304. **
  305. ** Raw test interface for sqlite3_realloc().
  306. */
  307. static int test_realloc(
  308. void * clientData,
  309. Tcl_Interp *interp,
  310. int objc,
  311. Tcl_Obj *CONST objv[]
  312. ){
  313. int nByte;
  314. void *pPrior, *p;
  315. char zOut[100];
  316. if( objc!=3 ){
  317. Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES");
  318. return TCL_ERROR;
  319. }
  320. if( Tcl_GetIntFromObj(interp, objv[2], &nByte) ) return TCL_ERROR;
  321. if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
  322. Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
  323. return TCL_ERROR;
  324. }
  325. p = sqlite3_realloc(pPrior, (unsigned)nByte);
  326. pointerToText(p, zOut);
  327. Tcl_AppendResult(interp, zOut, NULL);
  328. return TCL_OK;
  329. }
  330. /*
  331. ** Usage: sqlite3_free PRIOR
  332. **
  333. ** Raw test interface for sqlite3_free().
  334. */
  335. static int test_free(
  336. void * clientData,
  337. Tcl_Interp *interp,
  338. int objc,
  339. Tcl_Obj *CONST objv[]
  340. ){
  341. void *pPrior;
  342. if( objc!=2 ){
  343. Tcl_WrongNumArgs(interp, 1, objv, "PRIOR");
  344. return TCL_ERROR;
  345. }
  346. if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
  347. Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
  348. return TCL_ERROR;
  349. }
  350. sqlite3_free(pPrior);
  351. return TCL_OK;
  352. }
  353. /*
  354. ** These routines are in test_hexio.c
  355. */
  356. int sqlite3TestHexToBin(const char *, int, char *);
  357. int sqlite3TestBinToHex(char*,int);
  358. /*
  359. ** Usage: memset ADDRESS SIZE HEX
  360. **
  361. ** Set a chunk of memory (obtained from malloc, probably) to a
  362. ** specified hex pattern.
  363. */
  364. static int test_memset(
  365. void * clientData,
  366. Tcl_Interp *interp,
  367. int objc,
  368. Tcl_Obj *CONST objv[]
  369. ){
  370. void *p;
  371. int size, n, i;
  372. char *zHex;
  373. char *zOut;
  374. char zBin[100];
  375. if( objc!=4 ){
  376. Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX");
  377. return TCL_ERROR;
  378. }
  379. if( textToPointer(Tcl_GetString(objv[1]), &p) ){
  380. Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
  381. return TCL_ERROR;
  382. }
  383. if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
  384. return TCL_ERROR;
  385. }
  386. if( size<=0 ){
  387. Tcl_AppendResult(interp, "size must be positive", (char*)0);
  388. return TCL_ERROR;
  389. }
  390. zHex = Tcl_GetStringFromObj(objv[3], &n);
  391. if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2;
  392. n = sqlite3TestHexToBin(zHex, n, zBin);
  393. if( n==0 ){
  394. Tcl_AppendResult(interp, "no data", (char*)0);
  395. return TCL_ERROR;
  396. }
  397. zOut = p;
  398. for(i=0; i<size; i++){
  399. zOut[i] = zBin[i%n];
  400. }
  401. return TCL_OK;
  402. }
  403. /*
  404. ** Usage: memget ADDRESS SIZE
  405. **
  406. ** Return memory as hexadecimal text.
  407. */
  408. static int test_memget(
  409. void * clientData,
  410. Tcl_Interp *interp,
  411. int objc,
  412. Tcl_Obj *CONST objv[]
  413. ){
  414. void *p;
  415. int size, n;
  416. char *zBin;
  417. char zHex[100];
  418. if( objc!=3 ){
  419. Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE");
  420. return TCL_ERROR;
  421. }
  422. if( textToPointer(Tcl_GetString(objv[1]), &p) ){
  423. Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
  424. return TCL_ERROR;
  425. }
  426. if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
  427. return TCL_ERROR;
  428. }
  429. if( size<=0 ){
  430. Tcl_AppendResult(interp, "size must be positive", (char*)0);
  431. return TCL_ERROR;
  432. }
  433. zBin = p;
  434. while( size>0 ){
  435. if( size>(sizeof(zHex)-1)/2 ){
  436. n = (sizeof(zHex)-1)/2;
  437. }else{
  438. n = size;
  439. }
  440. memcpy(zHex, zBin, n);
  441. zBin += n;
  442. size -= n;
  443. sqlite3TestBinToHex(zHex, n);
  444. Tcl_AppendResult(interp, zHex, (char*)0);
  445. }
  446. return TCL_OK;
  447. }
  448. /*
  449. ** Usage: sqlite3_memory_used
  450. **
  451. ** Raw test interface for sqlite3_memory_used().
  452. */
  453. static int test_memory_used(
  454. void * clientData,
  455. Tcl_Interp *interp,
  456. int objc,
  457. Tcl_Obj *CONST objv[]
  458. ){
  459. Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_memory_used()));
  460. return TCL_OK;
  461. }
  462. /*
  463. ** Usage: sqlite3_memory_highwater ?RESETFLAG?
  464. **
  465. ** Raw test interface for sqlite3_memory_highwater().
  466. */
  467. static int test_memory_highwater(
  468. void * clientData,
  469. Tcl_Interp *interp,
  470. int objc,
  471. Tcl_Obj *CONST objv[]
  472. ){
  473. int resetFlag = 0;
  474. if( objc!=1 && objc!=2 ){
  475. Tcl_WrongNumArgs(interp, 1, objv, "?RESET?");
  476. return TCL_ERROR;
  477. }
  478. if( objc==2 ){
  479. if( Tcl_GetBooleanFromObj(interp, objv[1], &resetFlag) ) return TCL_ERROR;
  480. }
  481. Tcl_SetObjResult(interp,
  482. Tcl_NewWideIntObj(sqlite3_memory_highwater(resetFlag)));
  483. return TCL_OK;
  484. }
  485. /*
  486. ** Usage: sqlite3_memdebug_backtrace DEPTH
  487. **
  488. ** Set the depth of backtracing. If SQLITE_MEMDEBUG is not defined
  489. ** then this routine is a no-op.
  490. */
  491. static int test_memdebug_backtrace(
  492. void * clientData,
  493. Tcl_Interp *interp,
  494. int objc,
  495. Tcl_Obj *CONST objv[]
  496. ){
  497. int depth;
  498. if( objc!=2 ){
  499. Tcl_WrongNumArgs(interp, 1, objv, "DEPT");
  500. return TCL_ERROR;
  501. }
  502. if( Tcl_GetIntFromObj(interp, objv[1], &depth) ) return TCL_ERROR;
  503. #ifdef SQLITE_MEMDEBUG
  504. {
  505. extern void sqlite3MemdebugBacktrace(int);
  506. sqlite3MemdebugBacktrace(depth);
  507. }
  508. #endif
  509. return TCL_OK;
  510. }
  511. /*
  512. ** Usage: sqlite3_memdebug_dump FILENAME
  513. **
  514. ** Write a summary of unfreed memory to FILENAME.
  515. */
  516. static int test_memdebug_dump(
  517. void * clientData,
  518. Tcl_Interp *interp,
  519. int objc,
  520. Tcl_Obj *CONST objv[]
  521. ){
  522. if( objc!=2 ){
  523. Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
  524. return TCL_ERROR;
  525. }
  526. #if defined(SQLITE_MEMDEBUG) || defined(SQLITE_MEMORY_SIZE) \
  527. || defined(SQLITE_POW2_MEMORY_SIZE)
  528. {
  529. extern void sqlite3MemdebugDump(const char*);
  530. sqlite3MemdebugDump(Tcl_GetString(objv[1]));
  531. }
  532. #endif
  533. return TCL_OK;
  534. }
  535. /*
  536. ** Usage: sqlite3_memdebug_malloc_count
  537. **
  538. ** Return the total number of times malloc() has been called.
  539. */
  540. static int test_memdebug_malloc_count(
  541. void * clientData,
  542. Tcl_Interp *interp,
  543. int objc,
  544. Tcl_Obj *CONST objv[]
  545. ){
  546. int nMalloc = -1;
  547. if( objc!=1 ){
  548. Tcl_WrongNumArgs(interp, 1, objv, "");
  549. return TCL_ERROR;
  550. }
  551. #if defined(SQLITE_MEMDEBUG)
  552. {
  553. extern int sqlite3MemdebugMallocCount();
  554. nMalloc = sqlite3MemdebugMallocCount();
  555. }
  556. #endif
  557. Tcl_SetObjResult(interp, Tcl_NewIntObj(nMalloc));
  558. return TCL_OK;
  559. }
  560. /*
  561. ** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS?
  562. **
  563. ** where options are:
  564. **
  565. ** -repeat <count>
  566. ** -benigncnt <varname>
  567. **
  568. ** Arrange for a simulated malloc() failure after COUNTER successes.
  569. ** If a repeat count is specified, the fault is repeated that many
  570. ** times.
  571. **
  572. ** Each call to this routine overrides the prior counter value.
  573. ** This routine returns the number of simulated failures that have
  574. ** happened since the previous call to this routine.
  575. **
  576. ** To disable simulated failures, use a COUNTER of -1.
  577. */
  578. static int test_memdebug_fail(
  579. void * clientData,
  580. Tcl_Interp *interp,
  581. int objc,
  582. Tcl_Obj *CONST objv[]
  583. ){
  584. int ii;
  585. int iFail;
  586. int nRepeat = 1;
  587. Tcl_Obj *pBenignCnt = 0;
  588. int nBenign;
  589. int nFail = 0;
  590. if( objc<2 ){
  591. Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?");
  592. return TCL_ERROR;
  593. }
  594. if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;
  595. for(ii=2; ii<objc; ii+=2){
  596. int nOption;
  597. char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption);
  598. char *zErr = 0;
  599. if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){
  600. if( ii==(objc-1) ){
  601. zErr = "option requires an argument: ";
  602. }else{
  603. if( Tcl_GetIntFromObj(interp, objv[ii+1], &nRepeat) ){
  604. return TCL_ERROR;
  605. }
  606. }
  607. }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){
  608. if( ii==(objc-1) ){
  609. zErr = "option requires an argument: ";
  610. }else{
  611. pBenignCnt = objv[ii+1];
  612. }
  613. }else{
  614. zErr = "unknown option: ";
  615. }
  616. if( zErr ){
  617. Tcl_AppendResult(interp, zErr, zOption, 0);
  618. return TCL_ERROR;
  619. }
  620. }
  621. nBenign = faultsimBenignFailures();
  622. nFail = faultsimFailures();
  623. faultsimConfig(iFail, nRepeat);
  624. if( pBenignCnt ){
  625. Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0);
  626. }
  627. Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail));
  628. return TCL_OK;
  629. }
  630. /*
  631. ** Usage: sqlite3_memdebug_pending
  632. **
  633. ** Return the number of malloc() calls that will succeed before a
  634. ** simulated failure occurs. A negative return value indicates that
  635. ** no malloc() failure is scheduled.
  636. */
  637. static int test_memdebug_pending(
  638. void * clientData,
  639. Tcl_Interp *interp,
  640. int objc,
  641. Tcl_Obj *CONST objv[]
  642. ){
  643. int nPending;
  644. if( objc!=1 ){
  645. Tcl_WrongNumArgs(interp, 1, objv, "");
  646. return TCL_ERROR;
  647. }
  648. nPending = faultsimPending();
  649. Tcl_SetObjResult(interp, Tcl_NewIntObj(nPending));
  650. return TCL_OK;
  651. }
  652. /*
  653. ** Usage: sqlite3_memdebug_settitle TITLE
  654. **
  655. ** Set a title string stored with each allocation. The TITLE is
  656. ** typically the name of the test that was running when the
  657. ** allocation occurred. The TITLE is stored with the allocation
  658. ** and can be used to figure out which tests are leaking memory.
  659. **
  660. ** Each title overwrite the previous.
  661. */
  662. static int test_memdebug_settitle(
  663. void * clientData,
  664. Tcl_Interp *interp,
  665. int objc,
  666. Tcl_Obj *CONST objv[]
  667. ){
  668. if( objc!=2 ){
  669. Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
  670. return TCL_ERROR;
  671. }
  672. #ifdef SQLITE_MEMDEBUG
  673. {
  674. const char *zTitle;
  675. extern int sqlite3MemdebugSettitle(const char*);
  676. zTitle = Tcl_GetString(objv[1]);
  677. sqlite3MemdebugSettitle(zTitle);
  678. }
  679. #endif
  680. return TCL_OK;
  681. }
  682. #define MALLOC_LOG_FRAMES 10
  683. #define MALLOC_LOG_KEYINTS ( \
  684. 10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int)) \
  685. )
  686. static Tcl_HashTable aMallocLog;
  687. static int mallocLogEnabled = 0;
  688. typedef struct MallocLog MallocLog;
  689. struct MallocLog {
  690. int nCall;
  691. int nByte;
  692. };
  693. #ifdef SQLITE_MEMDEBUG
  694. static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
  695. if( mallocLogEnabled ){
  696. MallocLog *pLog;
  697. Tcl_HashEntry *pEntry;
  698. int isNew;
  699. int aKey[MALLOC_LOG_KEYINTS];
  700. unsigned int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
  701. memset(aKey, 0, nKey);
  702. if( (sizeof(void*)*nFrame)<nKey ){
  703. nKey = nFrame*sizeof(void*);
  704. }
  705. memcpy(aKey, aFrame, nKey);
  706. pEntry = Tcl_CreateHashEntry(&aMallocLog, (const char *)aKey, &isNew);
  707. if( isNew ){
  708. pLog = (MallocLog *)Tcl_Alloc(sizeof(MallocLog));
  709. memset(pLog, 0, sizeof(MallocLog));
  710. Tcl_SetHashValue(pEntry, (ClientData)pLog);
  711. }else{
  712. pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
  713. }
  714. pLog->nCall++;
  715. pLog->nByte += nByte;
  716. }
  717. }
  718. #endif /* SQLITE_MEMDEBUG */
  719. static void test_memdebug_log_clear(void){
  720. Tcl_HashSearch search;
  721. Tcl_HashEntry *pEntry;
  722. for(
  723. pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
  724. pEntry;
  725. pEntry=Tcl_NextHashEntry(&search)
  726. ){
  727. MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
  728. Tcl_Free((char *)pLog);
  729. }
  730. Tcl_DeleteHashTable(&aMallocLog);
  731. Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
  732. }
  733. static int test_memdebug_log(
  734. void * clientData,
  735. Tcl_Interp *interp,
  736. int objc,
  737. Tcl_Obj *CONST objv[]
  738. ){
  739. static int isInit = 0;
  740. int iSub;
  741. static const char *MB_strs[] = { "start", "stop", "dump", "clear", "sync" };
  742. enum MB_enum {
  743. MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR, MB_LOG_SYNC
  744. };
  745. if( !isInit ){
  746. #ifdef SQLITE_MEMDEBUG
  747. extern void sqlite3MemdebugBacktraceCallback(
  748. void (*xBacktrace)(int, int, void **));
  749. sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
  750. #endif
  751. Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
  752. isInit = 1;
  753. }
  754. if( objc<2 ){
  755. Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
  756. }
  757. if( Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, &iSub) ){
  758. return TCL_ERROR;
  759. }
  760. switch( (enum MB_enum)iSub ){
  761. case MB_LOG_START:
  762. mallocLogEnabled = 1;
  763. break;
  764. case MB_LOG_STOP:
  765. mallocLogEnabled = 0;
  766. break;
  767. case MB_LOG_DUMP: {
  768. Tcl_HashSearch search;
  769. Tcl_HashEntry *pEntry;
  770. Tcl_Obj *pRet = Tcl_NewObj();
  771. assert(sizeof(Tcl_WideInt)>=sizeof(void*));
  772. for(
  773. pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
  774. pEntry;
  775. pEntry=Tcl_NextHashEntry(&search)
  776. ){
  777. Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
  778. MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
  779. Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry);
  780. int ii;
  781. apElem[0] = Tcl_NewIntObj(pLog->nCall);
  782. apElem[1] = Tcl_NewIntObj(pLog->nByte);
  783. for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
  784. apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]);
  785. }
  786. Tcl_ListObjAppendElement(interp, pRet,
  787. Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem)
  788. );
  789. }
  790. Tcl_SetObjResult(interp, pRet);
  791. break;
  792. }
  793. case MB_LOG_CLEAR: {
  794. test_memdebug_log_clear();
  795. break;
  796. }
  797. case MB_LOG_SYNC: {
  798. #ifdef SQLITE_MEMDEBUG
  799. extern void sqlite3MemdebugSync();
  800. test_memdebug_log_clear();
  801. mallocLogEnabled = 1;
  802. sqlite3MemdebugSync();
  803. #endif
  804. break;
  805. }
  806. }
  807. return TCL_OK;
  808. }
  809. /*
  810. ** Usage: sqlite3_config_scratch SIZE N
  811. **
  812. ** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH.
  813. ** The buffer is static and is of limited size. N might be
  814. ** adjusted downward as needed to accomodate the requested size.
  815. ** The revised value of N is returned.
  816. **
  817. ** A negative SIZE causes the buffer pointer to be NULL.
  818. */
  819. static int test_config_scratch(
  820. void * clientData,
  821. Tcl_Interp *interp,
  822. int objc,
  823. Tcl_Obj *CONST objv[]
  824. ){
  825. int sz, N, rc;
  826. Tcl_Obj *pResult;
  827. static char *buf = 0;
  828. if( objc!=3 ){
  829. Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
  830. return TCL_ERROR;
  831. }
  832. if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
  833. if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
  834. free(buf);
  835. if( sz<0 ){
  836. buf = 0;
  837. rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0);
  838. }else{
  839. buf = malloc( sz*N + 1 );
  840. rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N);
  841. }
  842. pResult = Tcl_NewObj();
  843. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  844. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N));
  845. Tcl_SetObjResult(interp, pResult);
  846. return TCL_OK;
  847. }
  848. /*
  849. ** Usage: sqlite3_config_pagecache SIZE N
  850. **
  851. ** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE.
  852. ** The buffer is static and is of limited size. N might be
  853. ** adjusted downward as needed to accomodate the requested size.
  854. ** The revised value of N is returned.
  855. **
  856. ** A negative SIZE causes the buffer pointer to be NULL.
  857. */
  858. static int test_config_pagecache(
  859. void * clientData,
  860. Tcl_Interp *interp,
  861. int objc,
  862. Tcl_Obj *CONST objv[]
  863. ){
  864. int sz, N, rc;
  865. Tcl_Obj *pResult;
  866. static char *buf = 0;
  867. if( objc!=3 ){
  868. Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
  869. return TCL_ERROR;
  870. }
  871. if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
  872. if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
  873. free(buf);
  874. if( sz<0 ){
  875. buf = 0;
  876. rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0);
  877. }else{
  878. buf = malloc( sz*N );
  879. rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
  880. }
  881. pResult = Tcl_NewObj();
  882. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  883. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N));
  884. Tcl_SetObjResult(interp, pResult);
  885. return TCL_OK;
  886. }
  887. /*
  888. ** Usage: sqlite3_config_alt_pcache INSTALL_FLAG DISCARD_CHANCE PRNG_SEED
  889. **
  890. ** Set up the alternative test page cache. Install if INSTALL_FLAG is
  891. ** true and uninstall (reverting to the default page cache) if INSTALL_FLAG
  892. ** is false. DISCARD_CHANGE is an integer between 0 and 100 inclusive
  893. ** which determines the chance of discarding a page when unpinned. 100
  894. ** is certainty. 0 is never. PRNG_SEED is the pseudo-random number generator
  895. ** seed.
  896. */
  897. static int test_alt_pcache(
  898. void * clientData,
  899. Tcl_Interp *interp,
  900. int objc,
  901. Tcl_Obj *CONST objv[]
  902. ){
  903. int installFlag;
  904. int discardChance = 0;
  905. int prngSeed = 0;
  906. int highStress = 0;
  907. extern void installTestPCache(int,unsigned,unsigned,unsigned);
  908. if( objc<2 || objc>5 ){
  909. Tcl_WrongNumArgs(interp, 1, objv,
  910. "INSTALLFLAG DISCARDCHANCE PRNGSEEED HIGHSTRESS");
  911. return TCL_ERROR;
  912. }
  913. if( Tcl_GetIntFromObj(interp, objv[1], &installFlag) ) return TCL_ERROR;
  914. if( objc>=3 && Tcl_GetIntFromObj(interp, objv[2], &discardChance) ){
  915. return TCL_ERROR;
  916. }
  917. if( objc>=4 && Tcl_GetIntFromObj(interp, objv[3], &prngSeed) ){
  918. return TCL_ERROR;
  919. }
  920. if( objc>=5 && Tcl_GetIntFromObj(interp, objv[4], &highStress) ){
  921. return TCL_ERROR;
  922. }
  923. if( discardChance<0 || discardChance>100 ){
  924. Tcl_AppendResult(interp, "discard-chance should be between 0 and 100",
  925. (char*)0);
  926. return TCL_ERROR;
  927. }
  928. installTestPCache(installFlag, (unsigned)discardChance, (unsigned)prngSeed,
  929. (unsigned)highStress);
  930. return TCL_OK;
  931. }
  932. /*
  933. ** Usage: sqlite3_config_memstatus BOOLEAN
  934. **
  935. ** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS.
  936. */
  937. static int test_config_memstatus(
  938. void * clientData,
  939. Tcl_Interp *interp,
  940. int objc,
  941. Tcl_Obj *CONST objv[]
  942. ){
  943. int enable, rc;
  944. if( objc!=2 ){
  945. Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
  946. return TCL_ERROR;
  947. }
  948. if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR;
  949. rc = sqlite3_config(SQLITE_CONFIG_MEMSTATUS, enable);
  950. Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  951. return TCL_OK;
  952. }
  953. /*
  954. ** Usage: sqlite3_config_lookaside SIZE COUNT
  955. **
  956. */
  957. static int test_config_lookaside(
  958. void * clientData,
  959. Tcl_Interp *interp,
  960. int objc,
  961. Tcl_Obj *CONST objv[]
  962. ){
  963. int sz, cnt;
  964. Tcl_Obj *pRet;
  965. if( objc!=3 ){
  966. Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
  967. return TCL_ERROR;
  968. }
  969. if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
  970. if( Tcl_GetIntFromObj(interp, objv[2], &cnt) ) return TCL_ERROR;
  971. pRet = Tcl_NewObj();
  972. Tcl_ListObjAppendElement(
  973. interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.szLookaside)
  974. );
  975. Tcl_ListObjAppendElement(
  976. interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.nLookaside)
  977. );
  978. sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
  979. Tcl_SetObjResult(interp, pRet);
  980. return TCL_OK;
  981. }
  982. /*
  983. ** Usage: sqlite3_db_config_lookaside CONNECTION BUFID SIZE COUNT
  984. **
  985. ** There are two static buffers with BUFID 1 and 2. Each static buffer
  986. ** is 10KB in size. A BUFID of 0 indicates that the buffer should be NULL
  987. ** which will cause sqlite3_db_config() to allocate space on its own.
  988. */
  989. static int test_db_config_lookaside(
  990. void * clientData,
  991. Tcl_Interp *interp,
  992. int objc,
  993. Tcl_Obj *CONST objv[]
  994. ){
  995. int rc;
  996. int sz, cnt;
  997. sqlite3 *db;
  998. int bufid;
  999. static char azBuf[2][10000];
  1000. extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  1001. if( objc!=5 ){
  1002. Tcl_WrongNumArgs(interp, 1, objv, "BUFID SIZE COUNT");
  1003. return TCL_ERROR;
  1004. }
  1005. if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  1006. if( Tcl_GetIntFromObj(interp, objv[2], &bufid) ) return TCL_ERROR;
  1007. if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
  1008. if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
  1009. if( bufid==0 ){
  1010. rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt);
  1011. }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
  1012. rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
  1013. }else{
  1014. Tcl_AppendResult(interp, "illegal arguments - see documentation", (char*)0);
  1015. return TCL_ERROR;
  1016. }
  1017. Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  1018. return TCL_OK;
  1019. }
  1020. /*
  1021. ** Usage: sqlite3_config_heap NBYTE NMINALLOC
  1022. */
  1023. static int test_config_heap(
  1024. void * clientData,
  1025. Tcl_Interp *interp,
  1026. int objc,
  1027. Tcl_Obj *CONST objv[]
  1028. ){
  1029. static char *zBuf; /* Use this memory */
  1030. int nByte; /* Size of buffer to pass to sqlite3_config() */
  1031. int nMinAlloc; /* Size of minimum allocation */
  1032. int rc; /* Return code of sqlite3_config() */
  1033. Tcl_Obj * CONST *aArg = &objv[1];
  1034. int nArg = objc-1;
  1035. if( nArg!=2 ){
  1036. Tcl_WrongNumArgs(interp, 1, objv, "NBYTE NMINALLOC");
  1037. return TCL_ERROR;
  1038. }
  1039. if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR;
  1040. if( Tcl_GetIntFromObj(interp, aArg[1], &nMinAlloc) ) return TCL_ERROR;
  1041. if( nByte==0 ){
  1042. free( zBuf );
  1043. zBuf = 0;
  1044. rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void*)0, 0, 0);
  1045. }else{
  1046. zBuf = realloc(zBuf, nByte);
  1047. rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc);
  1048. }
  1049. Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1050. return TCL_OK;
  1051. }
  1052. /*
  1053. ** Usage: sqlite3_config_error [DB]
  1054. **
  1055. ** Invoke sqlite3_config() or sqlite3_db_config() with invalid
  1056. ** opcodes and verify that they return errors.
  1057. */
  1058. static int test_config_error(
  1059. void * clientData,
  1060. Tcl_Interp *interp,
  1061. int objc,
  1062. Tcl_Obj *CONST objv[]
  1063. ){
  1064. sqlite3 *db;
  1065. extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  1066. if( objc!=2 && objc!=1 ){
  1067. Tcl_WrongNumArgs(interp, 1, objv, "[DB]");
  1068. return TCL_ERROR;
  1069. }
  1070. if( objc==2 ){
  1071. if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  1072. if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){
  1073. Tcl_AppendResult(interp,
  1074. "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR",
  1075. (char*)0);
  1076. return TCL_ERROR;
  1077. }
  1078. }else{
  1079. if( sqlite3_config(99999)!=SQLITE_ERROR ){
  1080. Tcl_AppendResult(interp,
  1081. "sqlite3_config(99999) does not return SQLITE_ERROR",
  1082. (char*)0);
  1083. return TCL_ERROR;
  1084. }
  1085. }
  1086. return TCL_OK;
  1087. }
  1088. /*
  1089. ** Usage: sqlite3_config_uri BOOLEAN
  1090. **
  1091. ** Enables or disables interpretation of URI parameters by default using
  1092. ** SQLITE_CONFIG_URI.
  1093. */
  1094. static int test_config_uri(
  1095. void * clientData,
  1096. Tcl_Interp *interp,
  1097. int objc,
  1098. Tcl_Obj *CONST objv[]
  1099. ){
  1100. int rc;
  1101. int bOpenUri;
  1102. if( objc!=2 ){
  1103. Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
  1104. return TCL_ERROR;
  1105. }
  1106. if( Tcl_GetBooleanFromObj(interp, objv[1], &bOpenUri) ){
  1107. return TCL_ERROR;
  1108. }
  1109. rc = sqlite3_config(SQLITE_CONFIG_URI, bOpenUri);
  1110. Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1111. return TCL_OK;
  1112. }
  1113. /*
  1114. ** Usage: sqlite3_config_cis BOOLEAN
  1115. **
  1116. ** Enables or disables the use of the covering-index scan optimization.
  1117. ** SQLITE_CONFIG_COVERING_INDEX_SCAN.
  1118. */
  1119. static int test_config_cis(
  1120. void * clientData,
  1121. Tcl_Interp *interp,
  1122. int objc,
  1123. Tcl_Obj *CONST objv[]
  1124. ){
  1125. int rc;
  1126. int bUseCis;
  1127. if( objc!=2 ){
  1128. Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
  1129. return TCL_ERROR;
  1130. }
  1131. if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){
  1132. return TCL_ERROR;
  1133. }
  1134. rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis);
  1135. Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1136. return TCL_OK;
  1137. }
  1138. /*
  1139. ** Usage: sqlite3_dump_memsys3 FILENAME
  1140. ** sqlite3_dump_memsys5 FILENAME
  1141. **
  1142. ** Write a summary of unfreed memsys3 allocations to FILENAME.
  1143. */
  1144. static int test_dump_memsys3(
  1145. void * clientData,
  1146. Tcl_Interp *interp,
  1147. int objc,
  1148. Tcl_Obj *CONST objv[]
  1149. ){
  1150. if( objc!=2 ){
  1151. Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
  1152. return TCL_ERROR;
  1153. }
  1154. switch( SQLITE_PTR_TO_INT(clientData) ){
  1155. case 3: {
  1156. #ifdef SQLITE_ENABLE_MEMSYS3
  1157. extern void sqlite3Memsys3Dump(const char*);
  1158. sqlite3Memsys3Dump(Tcl_GetString(objv[1]));
  1159. break;
  1160. #endif
  1161. }
  1162. case 5: {
  1163. #ifdef SQLITE_ENABLE_MEMSYS5
  1164. extern void sqlite3Memsys5Dump(const char*);
  1165. sqlite3Memsys5Dump(Tcl_GetString(objv[1]));
  1166. break;
  1167. #endif
  1168. }
  1169. }
  1170. return TCL_OK;
  1171. }
  1172. /*
  1173. ** Usage: sqlite3_status OPCODE RESETFLAG
  1174. **
  1175. ** Return a list of three elements which are the sqlite3_status() return
  1176. ** code, the current value, and the high-water mark value.
  1177. */
  1178. static int test_status(
  1179. void * clientData,
  1180. Tcl_Interp *interp,
  1181. int objc,
  1182. Tcl_Obj *CONST objv[]
  1183. ){
  1184. int rc, iValue, mxValue;
  1185. int i, op, resetFlag;
  1186. const char *zOpName;
  1187. static const struct {
  1188. const char *zName;
  1189. int op;
  1190. } aOp[] = {
  1191. { "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED },
  1192. { "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE },
  1193. { "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED },
  1194. { "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW },
  1195. { "SQLITE_STATUS_PAGECACHE_SIZE", SQLITE_STATUS_PAGECACHE_SIZE },
  1196. { "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED },
  1197. { "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW },
  1198. { "SQLITE_STATUS_SCRATCH_SIZE", SQLITE_STATUS_SCRATCH_SIZE },
  1199. { "SQLITE_STATUS_PARSER_STACK", SQLITE_STATUS_PARSER_STACK },
  1200. { "SQLITE_STATUS_MALLOC_COUNT", SQLITE_STATUS_MALLOC_COUNT },
  1201. };
  1202. Tcl_Obj *pResult;
  1203. if( objc!=3 ){
  1204. Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
  1205. return TCL_ERROR;
  1206. }
  1207. zOpName = Tcl_GetString(objv[1]);
  1208. for(i=0; i<ArraySize(aOp); i++){
  1209. if( strcmp(aOp[i].zName, zOpName)==0 ){
  1210. op = aOp[i].op;
  1211. break;
  1212. }
  1213. }
  1214. if( i>=ArraySize(aOp) ){
  1215. if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR;
  1216. }
  1217. if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR;
  1218. iValue = 0;
  1219. mxValue = 0;
  1220. rc = sqlite3_status(op, &iValue, &mxValue, resetFlag);
  1221. pResult = Tcl_NewObj();
  1222. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  1223. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
  1224. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
  1225. Tcl_SetObjResult(interp, pResult);
  1226. return TCL_OK;
  1227. }
  1228. /*
  1229. ** Usage: sqlite3_db_status DATABASE OPCODE RESETFLAG
  1230. **
  1231. ** Return a list of three elements which are the sqlite3_db_status() return
  1232. ** code, the current value, and the high-water mark value.
  1233. */
  1234. static int test_db_status(
  1235. void * clientData,
  1236. Tcl_Interp *interp,
  1237. int objc,
  1238. Tcl_Obj *CONST objv[]
  1239. ){
  1240. int rc, iValue, mxValue;
  1241. int i, op, resetFlag;
  1242. const char *zOpName;
  1243. sqlite3 *db;
  1244. extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  1245. static const struct {
  1246. const char *zName;
  1247. int op;
  1248. } aOp[] = {
  1249. { "LOOKASIDE_USED", SQLITE_DBSTATUS_LOOKASIDE_USED },
  1250. { "CACHE_USED", SQLITE_DBSTATUS_CACHE_USED },
  1251. { "SCHEMA_USED", SQLITE_DBSTATUS_SCHEMA_USED },
  1252. { "STMT_USED", SQLITE_DBSTATUS_STMT_USED },
  1253. { "LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT },
  1254. { "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE },
  1255. { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL },
  1256. { "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT },
  1257. { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS },
  1258. { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE },
  1259. { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS }
  1260. };
  1261. Tcl_Obj *pResult;
  1262. if( objc!=4 ){
  1263. Tcl_WrongNumArgs(interp, 1, objv, "DB PARAMETER RESETFLAG");
  1264. return TCL_ERROR;
  1265. }
  1266. if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  1267. zOpName = Tcl_GetString(objv[2]);
  1268. if( memcmp(zOpName, "SQLITE_", 7)==0 ) zOpName += 7;
  1269. if( memcmp(zOpName, "DBSTATUS_", 9)==0 ) zOpName += 9;
  1270. for(i=0; i<ArraySize(aOp); i++){
  1271. if( strcmp(aOp[i].zName, zOpName)==0 ){
  1272. op = aOp[i].op;
  1273. break;
  1274. }
  1275. }
  1276. if( i>=ArraySize(aOp) ){
  1277. if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
  1278. }
  1279. if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
  1280. iValue = 0;
  1281. mxValue = 0;
  1282. rc = sqlite3_db_status(db, op, &iValue, &mxValue, resetFlag);
  1283. pResult = Tcl_NewObj();
  1284. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  1285. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
  1286. Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
  1287. Tcl_SetObjResult(interp, pResult);
  1288. return TCL_OK;
  1289. }
  1290. /*
  1291. ** install_malloc_faultsim BOOLEAN
  1292. */
  1293. static int test_install_malloc_faultsim(
  1294. void * clientData,
  1295. Tcl_Interp *interp,
  1296. int objc,
  1297. Tcl_Obj *CONST objv[]
  1298. ){
  1299. int rc;
  1300. int isInstall;
  1301. if( objc!=2 ){
  1302. Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
  1303. return TCL_ERROR;
  1304. }
  1305. if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
  1306. return TCL_ERROR;
  1307. }
  1308. rc = faultsimInstall(isInstall);
  1309. Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1310. return TCL_OK;
  1311. }
  1312. /*
  1313. ** sqlite3_install_memsys3
  1314. */
  1315. static int test_install_memsys3(
  1316. void * clientData,
  1317. Tcl_Interp *interp,
  1318. int objc,
  1319. Tcl_Obj *CONST objv[]
  1320. ){
  1321. int rc = SQLITE_MISUSE;
  1322. #ifdef SQLITE_ENABLE_MEMSYS3
  1323. const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
  1324. rc = sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetMemsys3());
  1325. #endif
  1326. Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1327. return TCL_OK;
  1328. }
  1329. static int test_vfs_oom_test(
  1330. void * clientData,
  1331. Tcl_Interp *interp,
  1332. int objc,
  1333. Tcl_Obj *CONST objv[]
  1334. ){
  1335. extern int sqlite3_memdebug_vfs_oom_test;
  1336. if( objc>2 ){
  1337. Tcl_WrongNumArgs(interp, 1, objv, "?INTEGER?");
  1338. return TCL_ERROR;
  1339. }else if( objc==2 ){
  1340. int iNew;
  1341. if( Tcl_GetIntFromObj(interp, objv[1], &iNew) ) return TCL_ERROR;
  1342. sqlite3_memdebug_vfs_oom_test = iNew;
  1343. }
  1344. Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_vfs_oom_test));
  1345. return TCL_OK;
  1346. }
  1347. /*
  1348. ** Register commands with the TCL interpreter.
  1349. */
  1350. int Sqlitetest_malloc_Init(Tcl_Interp *interp){
  1351. static struct {
  1352. char *zName;
  1353. Tcl_ObjCmdProc *xProc;
  1354. int clientData;
  1355. } aObjCmd[] = {
  1356. { "sqlite3_malloc", test_malloc ,0 },
  1357. { "sqlite3_realloc", test_realloc ,0 },
  1358. { "sqlite3_free", test_free ,0 },
  1359. { "memset", test_memset ,0 },
  1360. { "memget", test_memget ,0 },
  1361. { "sqlite3_memory_used", test_memory_used ,0 },
  1362. { "sqlite3_memory_highwater", test_memory_highwater ,0 },
  1363. { "sqlite3_memdebug_backtrace", test_memdebug_backtrace ,0 },
  1364. { "sqlite3_memdebug_dump", test_memdebug_dump ,0 },
  1365. { "sqlite3_memdebug_fail", test_memdebug_fail ,0 },
  1366. { "sqlite3_memdebug_pending", test_memdebug_pending ,0 },
  1367. { "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 },
  1368. { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 },
  1369. { "sqlite3_memdebug_log", test_memdebug_log ,0 },
  1370. { "sqlite3_config_scratch", test_config_scratch ,0 },
  1371. { "sqlite3_config_pagecache", test_config_pagecache ,0 },
  1372. { "sqlite3_config_alt_pcache", test_alt_pcache ,0 },
  1373. { "sqlite3_status", test_status ,0 },
  1374. { "sqlite3_db_status", test_db_status ,0 },
  1375. { "install_malloc_faultsim", test_install_malloc_faultsim ,0 },
  1376. { "sqlite3_config_heap", test_config_heap ,0 },
  1377. { "sqlite3_config_memstatus", test_config_memstatus ,0 },
  1378. { "sqlite3_config_lookaside", test_config_lookaside ,0 },
  1379. { "sqlite3_config_error", test_config_error ,0 },
  1380. { "sqlite3_config_uri", test_config_uri ,0 },
  1381. { "sqlite3_config_cis", test_config_cis ,0 },
  1382. { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
  1383. { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
  1384. { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
  1385. { "sqlite3_install_memsys3", test_install_memsys3 ,0 },
  1386. { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 },
  1387. };
  1388. int i;
  1389. for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
  1390. ClientData c = (ClientData)SQLITE_INT_TO_PTR(aObjCmd[i].clientData);
  1391. Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
  1392. }
  1393. return TCL_OK;
  1394. }
  1395. #endif