| OLD | NEW | 
 | (Empty) | 
|    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 low-level memory allocation drivers for when |  | 
|   14 ** SQLite will use the standard C-library malloc/realloc/free interface |  | 
|   15 ** to obtain the memory it needs while adding lots of additional debugging |  | 
|   16 ** information to each allocation in order to help detect and fix memory |  | 
|   17 ** leaks and memory usage errors. |  | 
|   18 ** |  | 
|   19 ** This file contains implementations of the low-level memory allocation |  | 
|   20 ** routines specified in the sqlite3_mem_methods object. |  | 
|   21 ** |  | 
|   22 ** $Id: mem2.c,v 1.45 2009/03/23 04:33:33 danielk1977 Exp $ |  | 
|   23 */ |  | 
|   24 #include "sqliteInt.h" |  | 
|   25  |  | 
|   26 /* |  | 
|   27 ** This version of the memory allocator is used only if the |  | 
|   28 ** SQLITE_MEMDEBUG macro is defined |  | 
|   29 */ |  | 
|   30 #ifdef SQLITE_MEMDEBUG |  | 
|   31  |  | 
|   32 /* |  | 
|   33 ** The backtrace functionality is only available with GLIBC |  | 
|   34 */ |  | 
|   35 #ifdef __GLIBC__ |  | 
|   36   extern int backtrace(void**,int); |  | 
|   37   extern void backtrace_symbols_fd(void*const*,int,int); |  | 
|   38 #else |  | 
|   39 # define backtrace(A,B) 1 |  | 
|   40 # define backtrace_symbols_fd(A,B,C) |  | 
|   41 #endif |  | 
|   42 #include <stdio.h> |  | 
|   43  |  | 
|   44 /* |  | 
|   45 ** Each memory allocation looks like this: |  | 
|   46 ** |  | 
|   47 **  ------------------------------------------------------------------------ |  | 
|   48 **  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard | |  | 
|   49 **  ------------------------------------------------------------------------ |  | 
|   50 ** |  | 
|   51 ** The application code sees only a pointer to the allocation.  We have |  | 
|   52 ** to back up from the allocation pointer to find the MemBlockHdr.  The |  | 
|   53 ** MemBlockHdr tells us the size of the allocation and the number of |  | 
|   54 ** backtrace pointers.  There is also a guard word at the end of the |  | 
|   55 ** MemBlockHdr. |  | 
|   56 */ |  | 
|   57 struct MemBlockHdr { |  | 
|   58   i64 iSize;                          /* Size of this allocation */ |  | 
|   59   struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */ |  | 
|   60   char nBacktrace;                    /* Number of backtraces on this alloc */ |  | 
|   61   char nBacktraceSlots;               /* Available backtrace slots */ |  | 
|   62   short nTitle;                       /* Bytes of title; includes '\0' */ |  | 
|   63   int iForeGuard;                     /* Guard word for sanity */ |  | 
|   64 }; |  | 
|   65  |  | 
|   66 /* |  | 
|   67 ** Guard words |  | 
|   68 */ |  | 
|   69 #define FOREGUARD 0x80F5E153 |  | 
|   70 #define REARGUARD 0xE4676B53 |  | 
|   71  |  | 
|   72 /* |  | 
|   73 ** Number of malloc size increments to track. |  | 
|   74 */ |  | 
|   75 #define NCSIZE  1000 |  | 
|   76  |  | 
|   77 /* |  | 
|   78 ** All of the static variables used by this module are collected |  | 
|   79 ** into a single structure named "mem".  This is to keep the |  | 
|   80 ** static variables organized and to reduce namespace pollution |  | 
|   81 ** when this module is combined with other in the amalgamation. |  | 
|   82 */ |  | 
|   83 static struct { |  | 
|   84    |  | 
|   85   /* |  | 
|   86   ** Mutex to control access to the memory allocation subsystem. |  | 
|   87   */ |  | 
|   88   sqlite3_mutex *mutex; |  | 
|   89  |  | 
|   90   /* |  | 
|   91   ** Head and tail of a linked list of all outstanding allocations |  | 
|   92   */ |  | 
|   93   struct MemBlockHdr *pFirst; |  | 
|   94   struct MemBlockHdr *pLast; |  | 
|   95    |  | 
|   96   /* |  | 
|   97   ** The number of levels of backtrace to save in new allocations. |  | 
|   98   */ |  | 
|   99   int nBacktrace; |  | 
|  100   void (*xBacktrace)(int, int, void **); |  | 
|  101  |  | 
|  102   /* |  | 
|  103   ** Title text to insert in front of each block |  | 
|  104   */ |  | 
|  105   int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */ |  | 
|  106   char zTitle[100];  /* The title text */ |  | 
|  107  |  | 
|  108   /*  |  | 
|  109   ** sqlite3MallocDisallow() increments the following counter. |  | 
|  110   ** sqlite3MallocAllow() decrements it. |  | 
|  111   */ |  | 
|  112   int disallow; /* Do not allow memory allocation */ |  | 
|  113  |  | 
|  114   /* |  | 
|  115   ** Gather statistics on the sizes of memory allocations. |  | 
|  116   ** nAlloc[i] is the number of allocation attempts of i*8 |  | 
|  117   ** bytes.  i==NCSIZE is the number of allocation attempts for |  | 
|  118   ** sizes more than NCSIZE*8 bytes. |  | 
|  119   */ |  | 
|  120   int nAlloc[NCSIZE];      /* Total number of allocations */ |  | 
|  121   int nCurrent[NCSIZE];    /* Current number of allocations */ |  | 
|  122   int mxCurrent[NCSIZE];   /* Highwater mark for nCurrent */ |  | 
|  123  |  | 
|  124 } mem; |  | 
|  125  |  | 
|  126  |  | 
|  127 /* |  | 
|  128 ** Adjust memory usage statistics |  | 
|  129 */ |  | 
|  130 static void adjustStats(int iSize, int increment){ |  | 
|  131   int i = ROUND8(iSize)/8; |  | 
|  132   if( i>NCSIZE-1 ){ |  | 
|  133     i = NCSIZE - 1; |  | 
|  134   } |  | 
|  135   if( increment>0 ){ |  | 
|  136     mem.nAlloc[i]++; |  | 
|  137     mem.nCurrent[i]++; |  | 
|  138     if( mem.nCurrent[i]>mem.mxCurrent[i] ){ |  | 
|  139       mem.mxCurrent[i] = mem.nCurrent[i]; |  | 
|  140     } |  | 
|  141   }else{ |  | 
|  142     mem.nCurrent[i]--; |  | 
|  143     assert( mem.nCurrent[i]>=0 ); |  | 
|  144   } |  | 
|  145 } |  | 
|  146  |  | 
|  147 /* |  | 
|  148 ** Given an allocation, find the MemBlockHdr for that allocation. |  | 
|  149 ** |  | 
|  150 ** This routine checks the guards at either end of the allocation and |  | 
|  151 ** if they are incorrect it asserts. |  | 
|  152 */ |  | 
|  153 static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ |  | 
|  154   struct MemBlockHdr *p; |  | 
|  155   int *pInt; |  | 
|  156   u8 *pU8; |  | 
|  157   int nReserve; |  | 
|  158  |  | 
|  159   p = (struct MemBlockHdr*)pAllocation; |  | 
|  160   p--; |  | 
|  161   assert( p->iForeGuard==(int)FOREGUARD ); |  | 
|  162   nReserve = ROUND8(p->iSize); |  | 
|  163   pInt = (int*)pAllocation; |  | 
|  164   pU8 = (u8*)pAllocation; |  | 
|  165   assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); |  | 
|  166   /* This checks any of the "extra" bytes allocated due |  | 
|  167   ** to rounding up to an 8 byte boundary to ensure  |  | 
|  168   ** they haven't been overwritten. |  | 
|  169   */ |  | 
|  170   while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); |  | 
|  171   return p; |  | 
|  172 } |  | 
|  173  |  | 
|  174 /* |  | 
|  175 ** Return the number of bytes currently allocated at address p. |  | 
|  176 */ |  | 
|  177 static int sqlite3MemSize(void *p){ |  | 
|  178   struct MemBlockHdr *pHdr; |  | 
|  179   if( !p ){ |  | 
|  180     return 0; |  | 
|  181   } |  | 
|  182   pHdr = sqlite3MemsysGetHeader(p); |  | 
|  183   return pHdr->iSize; |  | 
|  184 } |  | 
|  185  |  | 
|  186 /* |  | 
|  187 ** Initialize the memory allocation subsystem. |  | 
|  188 */ |  | 
|  189 static int sqlite3MemInit(void *NotUsed){ |  | 
|  190   UNUSED_PARAMETER(NotUsed); |  | 
|  191   assert( (sizeof(struct MemBlockHdr)&7) == 0 ); |  | 
|  192   if( !sqlite3GlobalConfig.bMemstat ){ |  | 
|  193     /* If memory status is enabled, then the malloc.c wrapper will already |  | 
|  194     ** hold the STATIC_MEM mutex when the routines here are invoked. */ |  | 
|  195     mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); |  | 
|  196   } |  | 
|  197   return SQLITE_OK; |  | 
|  198 } |  | 
|  199  |  | 
|  200 /* |  | 
|  201 ** Deinitialize the memory allocation subsystem. |  | 
|  202 */ |  | 
|  203 static void sqlite3MemShutdown(void *NotUsed){ |  | 
|  204   UNUSED_PARAMETER(NotUsed); |  | 
|  205   mem.mutex = 0; |  | 
|  206 } |  | 
|  207  |  | 
|  208 /* |  | 
|  209 ** Round up a request size to the next valid allocation size. |  | 
|  210 */ |  | 
|  211 static int sqlite3MemRoundup(int n){ |  | 
|  212   return ROUND8(n); |  | 
|  213 } |  | 
|  214  |  | 
|  215 /* |  | 
|  216 ** Allocate nByte bytes of memory. |  | 
|  217 */ |  | 
|  218 static void *sqlite3MemMalloc(int nByte){ |  | 
|  219   struct MemBlockHdr *pHdr; |  | 
|  220   void **pBt; |  | 
|  221   char *z; |  | 
|  222   int *pInt; |  | 
|  223   void *p = 0; |  | 
|  224   int totalSize; |  | 
|  225   int nReserve; |  | 
|  226   sqlite3_mutex_enter(mem.mutex); |  | 
|  227   assert( mem.disallow==0 ); |  | 
|  228   nReserve = ROUND8(nByte); |  | 
|  229   totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + |  | 
|  230                mem.nBacktrace*sizeof(void*) + mem.nTitle; |  | 
|  231   p = malloc(totalSize); |  | 
|  232   if( p ){ |  | 
|  233     z = p; |  | 
|  234     pBt = (void**)&z[mem.nTitle]; |  | 
|  235     pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; |  | 
|  236     pHdr->pNext = 0; |  | 
|  237     pHdr->pPrev = mem.pLast; |  | 
|  238     if( mem.pLast ){ |  | 
|  239       mem.pLast->pNext = pHdr; |  | 
|  240     }else{ |  | 
|  241       mem.pFirst = pHdr; |  | 
|  242     } |  | 
|  243     mem.pLast = pHdr; |  | 
|  244     pHdr->iForeGuard = FOREGUARD; |  | 
|  245     pHdr->nBacktraceSlots = mem.nBacktrace; |  | 
|  246     pHdr->nTitle = mem.nTitle; |  | 
|  247     if( mem.nBacktrace ){ |  | 
|  248       void *aAddr[40]; |  | 
|  249       pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; |  | 
|  250       memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); |  | 
|  251       assert(pBt[0]); |  | 
|  252       if( mem.xBacktrace ){ |  | 
|  253         mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); |  | 
|  254       } |  | 
|  255     }else{ |  | 
|  256       pHdr->nBacktrace = 0; |  | 
|  257     } |  | 
|  258     if( mem.nTitle ){ |  | 
|  259       memcpy(z, mem.zTitle, mem.nTitle); |  | 
|  260     } |  | 
|  261     pHdr->iSize = nByte; |  | 
|  262     adjustStats(nByte, +1); |  | 
|  263     pInt = (int*)&pHdr[1]; |  | 
|  264     pInt[nReserve/sizeof(int)] = REARGUARD; |  | 
|  265     memset(pInt, 0x65, nReserve); |  | 
|  266     p = (void*)pInt; |  | 
|  267   } |  | 
|  268   sqlite3_mutex_leave(mem.mutex); |  | 
|  269   return p;  |  | 
|  270 } |  | 
|  271  |  | 
|  272 /* |  | 
|  273 ** Free memory. |  | 
|  274 */ |  | 
|  275 static void sqlite3MemFree(void *pPrior){ |  | 
|  276   struct MemBlockHdr *pHdr; |  | 
|  277   void **pBt; |  | 
|  278   char *z; |  | 
|  279   assert( sqlite3GlobalConfig.bMemstat || mem.mutex!=0 ); |  | 
|  280   pHdr = sqlite3MemsysGetHeader(pPrior); |  | 
|  281   pBt = (void**)pHdr; |  | 
|  282   pBt -= pHdr->nBacktraceSlots; |  | 
|  283   sqlite3_mutex_enter(mem.mutex); |  | 
|  284   if( pHdr->pPrev ){ |  | 
|  285     assert( pHdr->pPrev->pNext==pHdr ); |  | 
|  286     pHdr->pPrev->pNext = pHdr->pNext; |  | 
|  287   }else{ |  | 
|  288     assert( mem.pFirst==pHdr ); |  | 
|  289     mem.pFirst = pHdr->pNext; |  | 
|  290   } |  | 
|  291   if( pHdr->pNext ){ |  | 
|  292     assert( pHdr->pNext->pPrev==pHdr ); |  | 
|  293     pHdr->pNext->pPrev = pHdr->pPrev; |  | 
|  294   }else{ |  | 
|  295     assert( mem.pLast==pHdr ); |  | 
|  296     mem.pLast = pHdr->pPrev; |  | 
|  297   } |  | 
|  298   z = (char*)pBt; |  | 
|  299   z -= pHdr->nTitle; |  | 
|  300   adjustStats(pHdr->iSize, -1); |  | 
|  301   memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |  | 
|  302                   pHdr->iSize + sizeof(int) + pHdr->nTitle); |  | 
|  303   free(z); |  | 
|  304   sqlite3_mutex_leave(mem.mutex);   |  | 
|  305 } |  | 
|  306  |  | 
|  307 /* |  | 
|  308 ** Change the size of an existing memory allocation. |  | 
|  309 ** |  | 
|  310 ** For this debugging implementation, we *always* make a copy of the |  | 
|  311 ** allocation into a new place in memory.  In this way, if the  |  | 
|  312 ** higher level code is using pointer to the old allocation, it is  |  | 
|  313 ** much more likely to break and we are much more liking to find |  | 
|  314 ** the error. |  | 
|  315 */ |  | 
|  316 static void *sqlite3MemRealloc(void *pPrior, int nByte){ |  | 
|  317   struct MemBlockHdr *pOldHdr; |  | 
|  318   void *pNew; |  | 
|  319   assert( mem.disallow==0 ); |  | 
|  320   pOldHdr = sqlite3MemsysGetHeader(pPrior); |  | 
|  321   pNew = sqlite3MemMalloc(nByte); |  | 
|  322   if( pNew ){ |  | 
|  323     memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |  | 
|  324     if( nByte>pOldHdr->iSize ){ |  | 
|  325       memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize); |  | 
|  326     } |  | 
|  327     sqlite3MemFree(pPrior); |  | 
|  328   } |  | 
|  329   return pNew; |  | 
|  330 } |  | 
|  331  |  | 
|  332 /* |  | 
|  333 ** Populate the low-level memory allocation function pointers in |  | 
|  334 ** sqlite3GlobalConfig.m with pointers to the routines in this file. |  | 
|  335 */ |  | 
|  336 void sqlite3MemSetDefault(void){ |  | 
|  337   static const sqlite3_mem_methods defaultMethods = { |  | 
|  338      sqlite3MemMalloc, |  | 
|  339      sqlite3MemFree, |  | 
|  340      sqlite3MemRealloc, |  | 
|  341      sqlite3MemSize, |  | 
|  342      sqlite3MemRoundup, |  | 
|  343      sqlite3MemInit, |  | 
|  344      sqlite3MemShutdown, |  | 
|  345      0 |  | 
|  346   }; |  | 
|  347   sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); |  | 
|  348 } |  | 
|  349  |  | 
|  350 /* |  | 
|  351 ** Set the number of backtrace levels kept for each allocation. |  | 
|  352 ** A value of zero turns off backtracing.  The number is always rounded |  | 
|  353 ** up to a multiple of 2. |  | 
|  354 */ |  | 
|  355 void sqlite3MemdebugBacktrace(int depth){ |  | 
|  356   if( depth<0 ){ depth = 0; } |  | 
|  357   if( depth>20 ){ depth = 20; } |  | 
|  358   depth = (depth+1)&0xfe; |  | 
|  359   mem.nBacktrace = depth; |  | 
|  360 } |  | 
|  361  |  | 
|  362 void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ |  | 
|  363   mem.xBacktrace = xBacktrace; |  | 
|  364 } |  | 
|  365  |  | 
|  366 /* |  | 
|  367 ** Set the title string for subsequent allocations. |  | 
|  368 */ |  | 
|  369 void sqlite3MemdebugSettitle(const char *zTitle){ |  | 
|  370   unsigned int n = sqlite3Strlen30(zTitle) + 1; |  | 
|  371   sqlite3_mutex_enter(mem.mutex); |  | 
|  372   if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; |  | 
|  373   memcpy(mem.zTitle, zTitle, n); |  | 
|  374   mem.zTitle[n] = 0; |  | 
|  375   mem.nTitle = ROUND8(n); |  | 
|  376   sqlite3_mutex_leave(mem.mutex); |  | 
|  377 } |  | 
|  378  |  | 
|  379 void sqlite3MemdebugSync(){ |  | 
|  380   struct MemBlockHdr *pHdr; |  | 
|  381   for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |  | 
|  382     void **pBt = (void**)pHdr; |  | 
|  383     pBt -= pHdr->nBacktraceSlots; |  | 
|  384     mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |  | 
|  385   } |  | 
|  386 } |  | 
|  387  |  | 
|  388 /* |  | 
|  389 ** Open the file indicated and write a log of all unfreed memory  |  | 
|  390 ** allocations into that log. |  | 
|  391 */ |  | 
|  392 void sqlite3MemdebugDump(const char *zFilename){ |  | 
|  393   FILE *out; |  | 
|  394   struct MemBlockHdr *pHdr; |  | 
|  395   void **pBt; |  | 
|  396   int i; |  | 
|  397   out = fopen(zFilename, "w"); |  | 
|  398   if( out==0 ){ |  | 
|  399     fprintf(stderr, "** Unable to output memory debug output log: %s **\n", |  | 
|  400                     zFilename); |  | 
|  401     return; |  | 
|  402   } |  | 
|  403   for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |  | 
|  404     char *z = (char*)pHdr; |  | 
|  405     z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; |  | 
|  406     fprintf(out, "**** %lld bytes at %p from %s ****\n",  |  | 
|  407             pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); |  | 
|  408     if( pHdr->nBacktrace ){ |  | 
|  409       fflush(out); |  | 
|  410       pBt = (void**)pHdr; |  | 
|  411       pBt -= pHdr->nBacktraceSlots; |  | 
|  412       backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); |  | 
|  413       fprintf(out, "\n"); |  | 
|  414     } |  | 
|  415   } |  | 
|  416   fprintf(out, "COUNTS:\n"); |  | 
|  417   for(i=0; i<NCSIZE-1; i++){ |  | 
|  418     if( mem.nAlloc[i] ){ |  | 
|  419       fprintf(out, "   %5d: %10d %10d %10d\n",  |  | 
|  420             i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]); |  | 
|  421     } |  | 
|  422   } |  | 
|  423   if( mem.nAlloc[NCSIZE-1] ){ |  | 
|  424     fprintf(out, "   %5d: %10d %10d %10d\n", |  | 
|  425              NCSIZE*8-8, mem.nAlloc[NCSIZE-1], |  | 
|  426              mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]); |  | 
|  427   } |  | 
|  428   fclose(out); |  | 
|  429 } |  | 
|  430  |  | 
|  431 /* |  | 
|  432 ** Return the number of times sqlite3MemMalloc() has been called. |  | 
|  433 */ |  | 
|  434 int sqlite3MemdebugMallocCount(){ |  | 
|  435   int i; |  | 
|  436   int nTotal = 0; |  | 
|  437   for(i=0; i<NCSIZE; i++){ |  | 
|  438     nTotal += mem.nAlloc[i]; |  | 
|  439   } |  | 
|  440   return nTotal; |  | 
|  441 } |  | 
|  442  |  | 
|  443  |  | 
|  444 #endif /* SQLITE_MEMDEBUG */ |  | 
| OLD | NEW |