mem2.c
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:12k
源码类别:

数据库系统

开发平台:

C/C++

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