⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_malloc.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** 2007 August 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.******************************************************************************* This file contains code used to implement test interfaces to the** memory allocation subsystem.**** $Id: test_malloc.c,v 1.47 2008/08/05 17:53:24 drh Exp $*/#include "sqliteInt.h"#include "tcl.h"#include <stdlib.h>#include <string.h>#include <assert.h>/*** This structure is used to encapsulate the global state variables used ** by malloc() fault simulation.*/static struct MemFault {  int iCountdown;         /* Number of pending successes before a failure */  int nRepeat;            /* Number of times to repeat the failure */  int nBenign;            /* Number of benign failures seen since last config */  int nFail;              /* Number of failures seen since last config */  u8 enable;              /* True if enabled */  int isInstalled;        /* True if the fault simulation layer is installed */  int isBenignMode;       /* True if malloc failures are considered benign */  sqlite3_mem_methods m;  /* 'Real' malloc implementation */} memfault;/*** This routine exists as a place to set a breakpoint that will** fire on any simulated malloc() failure.*/static void sqlite3Fault(void){  static int cnt = 0;  cnt++;}/*** Check to see if a fault should be simulated.  Return true to simulate** the fault.  Return false if the fault should not be simulated.*/static int faultsimStep(){  if( likely(!memfault.enable) ){    return 0;  }  if( memfault.iCountdown>0 ){    memfault.iCountdown--;    return 0;  }  sqlite3Fault();  memfault.nFail++;  if( memfault.isBenignMode>0 ){    memfault.nBenign++;  }  memfault.nRepeat--;  if( memfault.nRepeat<=0 ){    memfault.enable = 0;  }  return 1;  }/*** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation** logic.*/static void *faultsimMalloc(int n){  void *p = 0;  if( !faultsimStep() ){    p = memfault.m.xMalloc(n);  }  return p;}/*** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation** logic.*/static void *faultsimRealloc(void *pOld, int n){  void *p = 0;  if( !faultsimStep() ){    p = memfault.m.xRealloc(pOld, n);  }  return p;}/* ** The following method calls are passed directly through to the underlying** malloc system:****     xFree**     xSize**     xRoundup**     xInit**     xShutdown*/static void faultsimFree(void *p){  memfault.m.xFree(p);}static int faultsimSize(void *p){  return memfault.m.xSize(p);}static int faultsimRoundup(int n){  return memfault.m.xRoundup(n);}static int faultsimInit(void *p){  return memfault.m.xInit(memfault.m.pAppData);}static void faultsimShutdown(void *p){  memfault.m.xShutdown(memfault.m.pAppData);}/*** This routine configures the malloc failure simulation.  After** calling this routine, the next nDelay mallocs will succeed, followed** by a block of nRepeat failures, after which malloc() calls will begin** to succeed again.*/static void faultsimConfig(int nDelay, int nRepeat){  memfault.iCountdown = nDelay;  memfault.nRepeat = nRepeat;  memfault.nBenign = 0;  memfault.nFail = 0;  memfault.enable = nDelay>=0;}/*** Return the number of faults (both hard and benign faults) that have** occurred since the injector was last configured.*/static int faultsimFailures(void){  return memfault.nFail;}/*** Return the number of benign faults that have occurred since the** injector was last configured.*/static int faultsimBenignFailures(void){  return memfault.nBenign;}/*** Return the number of successes that will occur before the next failure.** If no failures are scheduled, return -1.*/static int faultsimPending(void){  if( memfault.enable ){    return memfault.iCountdown;  }else{    return -1;  }}static void faultsimBeginBenign(void){  memfault.isBenignMode++;}static void faultsimEndBenign(void){  memfault.isBenignMode--;}/*** Add or remove the fault-simulation layer using sqlite3_config(). If** the argument is non-zero, the */static int faultsimInstall(int install){  static struct sqlite3_mem_methods m = {    faultsimMalloc,                   /* xMalloc */    faultsimFree,                     /* xFree */    faultsimRealloc,                  /* xRealloc */    faultsimSize,                     /* xSize */    faultsimRoundup,                  /* xRoundup */    faultsimInit,                     /* xInit */    faultsimShutdown,                 /* xShutdown */    0                                 /* pAppData */  };  int rc;  install = (install ? 1 : 0);  assert(memfault.isInstalled==1 || memfault.isInstalled==0);  if( install==memfault.isInstalled ){    return SQLITE_ERROR;  }  if( install ){    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);    assert(memfault.m.xMalloc);    if( rc==SQLITE_OK ){      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);    }    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,         faultsimBeginBenign, faultsimEndBenign    );  }else{    assert(memfault.m.xMalloc);    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);  }  if( rc==SQLITE_OK ){    memfault.isInstalled = 1;  }  return rc;}#ifdef SQLITE_TEST/*** This function is implemented in test1.c. Returns a pointer to a static** buffer containing the symbolic SQLite error code that corresponds to** the least-significant 8-bits of the integer passed as an argument.** For example:****   sqlite3TestErrorName(1) -> "SQLITE_ERROR"*/const char *sqlite3TestErrorName(int);/*** Transform pointers to text and back again*/static void pointerToText(void *p, char *z){  static const char zHex[] = "0123456789abcdef";  int i, k;  unsigned int u;  sqlite3_uint64 n;  if( p==0 ){    strcpy(z, "0");    return;  }  if( sizeof(n)==sizeof(p) ){    memcpy(&n, &p, sizeof(p));  }else if( sizeof(u)==sizeof(p) ){    memcpy(&u, &p, sizeof(u));    n = u;  }else{    assert( 0 );  }  for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){    z[k] = zHex[n&0xf];    n >>= 4;  }  z[sizeof(p)*2] = 0;}static int hexToInt(int h){  if( h>='0' && h<='9' ){    return h - '0';  }else if( h>='a' && h<='f' ){    return h - 'a' + 10;  }else{    return -1;  }}static int textToPointer(const char *z, void **pp){  sqlite3_uint64 n = 0;  int i;  unsigned int u;  for(i=0; i<sizeof(void*)*2 && z[0]; i++){    int v;    v = hexToInt(*z++);    if( v<0 ) return TCL_ERROR;    n = n*16 + v;  }  if( *z!=0 ) return TCL_ERROR;  if( sizeof(n)==sizeof(*pp) ){    memcpy(pp, &n, sizeof(n));  }else if( sizeof(u)==sizeof(*pp) ){    u = (unsigned int)n;    memcpy(pp, &u, sizeof(u));  }else{    assert( 0 );  }  return TCL_OK;}/*** Usage:    sqlite3_malloc  NBYTES**** Raw test interface for sqlite3_malloc().*/static int test_malloc(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int nByte;  void *p;  char zOut[100];  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "NBYTES");    return TCL_ERROR;  }  if( Tcl_GetIntFromObj(interp, objv[1], &nByte) ) return TCL_ERROR;  p = sqlite3_malloc((unsigned)nByte);  pointerToText(p, zOut);  Tcl_AppendResult(interp, zOut, NULL);  return TCL_OK;}/*** Usage:    sqlite3_realloc  PRIOR  NBYTES**** Raw test interface for sqlite3_realloc().*/static int test_realloc(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int nByte;  void *pPrior, *p;  char zOut[100];  if( objc!=3 ){    Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES");    return TCL_ERROR;  }  if( Tcl_GetIntFromObj(interp, objv[2], &nByte) ) return TCL_ERROR;  if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);    return TCL_ERROR;  }  p = sqlite3_realloc(pPrior, (unsigned)nByte);  pointerToText(p, zOut);  Tcl_AppendResult(interp, zOut, NULL);  return TCL_OK;}/*** Usage:    sqlite3_free  PRIOR**** Raw test interface for sqlite3_free().*/static int test_free(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  void *pPrior;  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "PRIOR");    return TCL_ERROR;  }  if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);    return TCL_ERROR;  }  sqlite3_free(pPrior);  return TCL_OK;}/*** These routines are in test_hexio.c*/int sqlite3TestHexToBin(const char *, int, char *);int sqlite3TestBinToHex(char*,int);/*** Usage:    memset  ADDRESS  SIZE  HEX**** Set a chunk of memory (obtained from malloc, probably) to a** specified hex pattern.*/static int test_memset(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  void *p;  int size, n, i;  char *zHex;  char *zOut;  char zBin[100];  if( objc!=4 ){    Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX");    return TCL_ERROR;  }  if( textToPointer(Tcl_GetString(objv[1]), &p) ){    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);    return TCL_ERROR;  }  if( Tcl_GetIntFromObj(interp, objv[2], &size) ){    return TCL_ERROR;  }  if( size<=0 ){    Tcl_AppendResult(interp, "size must be positive", (char*)0);    return TCL_ERROR;  }  zHex = Tcl_GetStringFromObj(objv[3], &n);  if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2;  n = sqlite3TestHexToBin(zHex, n, zBin);  if( n==0 ){    Tcl_AppendResult(interp, "no data", (char*)0);    return TCL_ERROR;  }  zOut = p;  for(i=0; i<size; i++){    zOut[i] = zBin[i%n];  }  return TCL_OK;}/*** Usage:    memget  ADDRESS  SIZE**** Return memory as hexadecimal text.*/static int test_memget(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  void *p;  int size, n;  char *zBin;  char zHex[100];  if( objc!=3 ){    Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE");    return TCL_ERROR;  }  if( textToPointer(Tcl_GetString(objv[1]), &p) ){    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);    return TCL_ERROR;  }  if( Tcl_GetIntFromObj(interp, objv[2], &size) ){    return TCL_ERROR;  }  if( size<=0 ){    Tcl_AppendResult(interp, "size must be positive", (char*)0);    return TCL_ERROR;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -