14c3645c6Sdrh /*
24c3645c6Sdrh ** 2007 August 15
34c3645c6Sdrh **
44c3645c6Sdrh ** The author disclaims copyright to this source code. In place of
54c3645c6Sdrh ** a legal notice, here is a blessing:
64c3645c6Sdrh **
74c3645c6Sdrh ** May you do good and not evil.
84c3645c6Sdrh ** May you find forgiveness for yourself and forgive others.
94c3645c6Sdrh ** May you share freely, never taking more than you give.
104c3645c6Sdrh **
114c3645c6Sdrh *************************************************************************
124c3645c6Sdrh **
13fec00eabSdrh ** This file contains low-level memory allocation drivers for when
14fec00eabSdrh ** SQLite will use the standard C-library malloc/realloc/free interface
15fec00eabSdrh ** to obtain the memory it needs while adding lots of additional debugging
16fec00eabSdrh ** information to each allocation in order to help detect and fix memory
17fec00eabSdrh ** leaks and memory usage errors.
18fec00eabSdrh **
19fec00eabSdrh ** This file contains implementations of the low-level memory allocation
20fec00eabSdrh ** routines specified in the sqlite3_mem_methods object.
214c3645c6Sdrh */
220d18020bSdrh #include "sqliteInt.h"
234c3645c6Sdrh
244c3645c6Sdrh /*
254c3645c6Sdrh ** This version of the memory allocator is used only if the
260d18020bSdrh ** SQLITE_MEMDEBUG macro is defined
274c3645c6Sdrh */
280d18020bSdrh #ifdef SQLITE_MEMDEBUG
294c3645c6Sdrh
304c3645c6Sdrh /*
314c3645c6Sdrh ** The backtrace functionality is only available with GLIBC
324c3645c6Sdrh */
334c3645c6Sdrh #ifdef __GLIBC__
344c3645c6Sdrh extern int backtrace(void**,int);
354c3645c6Sdrh extern void backtrace_symbols_fd(void*const*,int,int);
364c3645c6Sdrh #else
3744a376f6Sdanielk1977 # define backtrace(A,B) 1
384c3645c6Sdrh # define backtrace_symbols_fd(A,B,C)
394c3645c6Sdrh #endif
400d18020bSdrh #include <stdio.h>
414c3645c6Sdrh
424c3645c6Sdrh /*
434c3645c6Sdrh ** Each memory allocation looks like this:
444c3645c6Sdrh **
454a50aac5Sdrh ** ------------------------------------------------------------------------
464a50aac5Sdrh ** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard |
474a50aac5Sdrh ** ------------------------------------------------------------------------
484c3645c6Sdrh **
494c3645c6Sdrh ** The application code sees only a pointer to the allocation. We have
504c3645c6Sdrh ** to back up from the allocation pointer to find the MemBlockHdr. The
514c3645c6Sdrh ** MemBlockHdr tells us the size of the allocation and the number of
524c3645c6Sdrh ** backtrace pointers. There is also a guard word at the end of the
534c3645c6Sdrh ** MemBlockHdr.
544c3645c6Sdrh */
554c3645c6Sdrh struct MemBlockHdr {
56fab69597Sdrh i64 iSize; /* Size of this allocation */
574c3645c6Sdrh struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */
58153c62c4Sdrh char nBacktrace; /* Number of backtraces on this alloc */
59153c62c4Sdrh char nBacktraceSlots; /* Available backtrace slots */
60107b56e8Sdrh u8 nTitle; /* Bytes of title; includes '\0' */
61107b56e8Sdrh u8 eType; /* Allocation type code */
62153c62c4Sdrh int iForeGuard; /* Guard word for sanity */
634c3645c6Sdrh };
644c3645c6Sdrh
654c3645c6Sdrh /*
664c3645c6Sdrh ** Guard words
674c3645c6Sdrh */
684c3645c6Sdrh #define FOREGUARD 0x80F5E153
694c3645c6Sdrh #define REARGUARD 0xE4676B53
704c3645c6Sdrh
714c3645c6Sdrh /*
72d2bb3278Sdrh ** Number of malloc size increments to track.
73d2bb3278Sdrh */
749c7a60dfSdrh #define NCSIZE 1000
75d2bb3278Sdrh
76d2bb3278Sdrh /*
770e6f1546Sdrh ** All of the static variables used by this module are collected
780e6f1546Sdrh ** into a single structure named "mem". This is to keep the
790e6f1546Sdrh ** static variables organized and to reduce namespace pollution
800e6f1546Sdrh ** when this module is combined with other in the amalgamation.
810e6f1546Sdrh */
820e6f1546Sdrh static struct {
830e6f1546Sdrh
840e6f1546Sdrh /*
850e6f1546Sdrh ** Mutex to control access to the memory allocation subsystem.
860e6f1546Sdrh */
870e6f1546Sdrh sqlite3_mutex *mutex;
880e6f1546Sdrh
890e6f1546Sdrh /*
904c3645c6Sdrh ** Head and tail of a linked list of all outstanding allocations
914c3645c6Sdrh */
920e6f1546Sdrh struct MemBlockHdr *pFirst;
930e6f1546Sdrh struct MemBlockHdr *pLast;
944c3645c6Sdrh
954c3645c6Sdrh /*
964c3645c6Sdrh ** The number of levels of backtrace to save in new allocations.
974c3645c6Sdrh */
980e6f1546Sdrh int nBacktrace;
996f332c18Sdanielk1977 void (*xBacktrace)(int, int, void **);
1000e6f1546Sdrh
1010e6f1546Sdrh /*
1024a50aac5Sdrh ** Title text to insert in front of each block
1034a50aac5Sdrh */
1044a50aac5Sdrh int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */
1054a50aac5Sdrh char zTitle[100]; /* The title text */
1064a50aac5Sdrh
1074a50aac5Sdrh /*
108d677b3d6Sdrh ** sqlite3MallocDisallow() increments the following counter.
109d677b3d6Sdrh ** sqlite3MallocAllow() decrements it.
110d677b3d6Sdrh */
111d677b3d6Sdrh int disallow; /* Do not allow memory allocation */
112d677b3d6Sdrh
113d2bb3278Sdrh /*
114d2bb3278Sdrh ** Gather statistics on the sizes of memory allocations.
1152abcd58fSdrh ** nAlloc[i] is the number of allocation attempts of i*8
116d2bb3278Sdrh ** bytes. i==NCSIZE is the number of allocation attempts for
1179c7a60dfSdrh ** sizes more than NCSIZE*8 bytes.
118d2bb3278Sdrh */
1192abcd58fSdrh int nAlloc[NCSIZE]; /* Total number of allocations */
1202abcd58fSdrh int nCurrent[NCSIZE]; /* Current number of allocations */
1212abcd58fSdrh int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */
1220e6f1546Sdrh
123153c62c4Sdrh } mem;
1240e6f1546Sdrh
1252abcd58fSdrh
1262abcd58fSdrh /*
1272abcd58fSdrh ** Adjust memory usage statistics
1282abcd58fSdrh */
adjustStats(int iSize,int increment)1292abcd58fSdrh static void adjustStats(int iSize, int increment){
130bc73971dSdanielk1977 int i = ROUND8(iSize)/8;
1312abcd58fSdrh if( i>NCSIZE-1 ){
1322abcd58fSdrh i = NCSIZE - 1;
1332abcd58fSdrh }
1342abcd58fSdrh if( increment>0 ){
1352abcd58fSdrh mem.nAlloc[i]++;
1362abcd58fSdrh mem.nCurrent[i]++;
1372abcd58fSdrh if( mem.nCurrent[i]>mem.mxCurrent[i] ){
1382abcd58fSdrh mem.mxCurrent[i] = mem.nCurrent[i];
1392abcd58fSdrh }
1402abcd58fSdrh }else{
1412abcd58fSdrh mem.nCurrent[i]--;
1422abcd58fSdrh assert( mem.nCurrent[i]>=0 );
1432abcd58fSdrh }
1442abcd58fSdrh }
1452abcd58fSdrh
1464c3645c6Sdrh /*
1474c3645c6Sdrh ** Given an allocation, find the MemBlockHdr for that allocation.
1484c3645c6Sdrh **
1494c3645c6Sdrh ** This routine checks the guards at either end of the allocation and
1504c3645c6Sdrh ** if they are incorrect it asserts.
1514c3645c6Sdrh */
sqlite3MemsysGetHeader(const void * pAllocation)152*04f1b691Smistachkin static struct MemBlockHdr *sqlite3MemsysGetHeader(const void *pAllocation){
1534c3645c6Sdrh struct MemBlockHdr *p;
154153c62c4Sdrh int *pInt;
155ce98bba2Sdanielk1977 u8 *pU8;
156ce98bba2Sdanielk1977 int nReserve;
1574c3645c6Sdrh
1584c3645c6Sdrh p = (struct MemBlockHdr*)pAllocation;
1594c3645c6Sdrh p--;
160902b9ee4Sdrh assert( p->iForeGuard==(int)FOREGUARD );
161bc73971dSdanielk1977 nReserve = ROUND8(p->iSize);
162153c62c4Sdrh pInt = (int*)pAllocation;
163ce98bba2Sdanielk1977 pU8 = (u8*)pAllocation;
164902b9ee4Sdrh assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
165d20010c7Sshane /* This checks any of the "extra" bytes allocated due
166d20010c7Sshane ** to rounding up to an 8 byte boundary to ensure
167d20010c7Sshane ** they haven't been overwritten.
168d20010c7Sshane */
169d20010c7Sshane while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
1704c3645c6Sdrh return p;
1714c3645c6Sdrh }
1724c3645c6Sdrh
1734c3645c6Sdrh /*
174a7a8e14bSdanielk1977 ** Return the number of bytes currently allocated at address p.
175a7a8e14bSdanielk1977 */
sqlite3MemSize(void * p)176fec00eabSdrh static int sqlite3MemSize(void *p){
177a7a8e14bSdanielk1977 struct MemBlockHdr *pHdr;
178a7a8e14bSdanielk1977 if( !p ){
179a7a8e14bSdanielk1977 return 0;
180a7a8e14bSdanielk1977 }
181a7a8e14bSdanielk1977 pHdr = sqlite3MemsysGetHeader(p);
182f6418891Smistachkin return (int)pHdr->iSize;
183a7a8e14bSdanielk1977 }
184a7a8e14bSdanielk1977
185a7a8e14bSdanielk1977 /*
186fec00eabSdrh ** Initialize the memory allocation subsystem.
18740257ffdSdrh */
sqlite3MemInit(void * NotUsed)188fec00eabSdrh static int sqlite3MemInit(void *NotUsed){
189902b9ee4Sdrh UNUSED_PARAMETER(NotUsed);
190d20010c7Sshane assert( (sizeof(struct MemBlockHdr)&7) == 0 );
191075c23afSdanielk1977 if( !sqlite3GlobalConfig.bMemstat ){
19265bbf29eSdrh /* If memory status is enabled, then the malloc.c wrapper will already
19365bbf29eSdrh ** hold the STATIC_MEM mutex when the routines here are invoked. */
19459f8c08eSdanielk1977 mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
19565bbf29eSdrh }
19640257ffdSdrh return SQLITE_OK;
19740257ffdSdrh }
19840257ffdSdrh
19940257ffdSdrh /*
200fec00eabSdrh ** Deinitialize the memory allocation subsystem.
201fec00eabSdrh */
sqlite3MemShutdown(void * NotUsed)202fec00eabSdrh static void sqlite3MemShutdown(void *NotUsed){
203902b9ee4Sdrh UNUSED_PARAMETER(NotUsed);
204fec00eabSdrh mem.mutex = 0;
205fec00eabSdrh }
206fec00eabSdrh
207fec00eabSdrh /*
208fec00eabSdrh ** Round up a request size to the next valid allocation size.
209fec00eabSdrh */
sqlite3MemRoundup(int n)210fec00eabSdrh static int sqlite3MemRoundup(int n){
211bc73971dSdanielk1977 return ROUND8(n);
212fec00eabSdrh }
213fec00eabSdrh
214fec00eabSdrh /*
21510f864e8Sdrh ** Fill a buffer with pseudo-random bytes. This is used to preset
21610f864e8Sdrh ** the content of a new memory allocation to unpredictable values and
21710f864e8Sdrh ** to clear the content of a freed allocation to unpredictable values.
21810f864e8Sdrh */
randomFill(char * pBuf,int nByte)21910f864e8Sdrh static void randomFill(char *pBuf, int nByte){
22010f864e8Sdrh unsigned int x, y, r;
22110f864e8Sdrh x = SQLITE_PTR_TO_INT(pBuf);
22210f864e8Sdrh y = nByte | 1;
22310f864e8Sdrh while( nByte >= 4 ){
224f6418891Smistachkin x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
22510f864e8Sdrh y = y*1103515245 + 12345;
22610f864e8Sdrh r = x ^ y;
22710f864e8Sdrh *(int*)pBuf = r;
22810f864e8Sdrh pBuf += 4;
22910f864e8Sdrh nByte -= 4;
23010f864e8Sdrh }
23110f864e8Sdrh while( nByte-- > 0 ){
232f6418891Smistachkin x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
23310f864e8Sdrh y = y*1103515245 + 12345;
23410f864e8Sdrh r = x ^ y;
23510f864e8Sdrh *(pBuf++) = r & 0xff;
23610f864e8Sdrh }
23710f864e8Sdrh }
23810f864e8Sdrh
23910f864e8Sdrh /*
2400e6f1546Sdrh ** Allocate nByte bytes of memory.
2414c3645c6Sdrh */
sqlite3MemMalloc(int nByte)242fec00eabSdrh static void *sqlite3MemMalloc(int nByte){
2434c3645c6Sdrh struct MemBlockHdr *pHdr;
2444c3645c6Sdrh void **pBt;
2454a50aac5Sdrh char *z;
246153c62c4Sdrh int *pInt;
247ca0c8971Sdanielk1977 void *p = 0;
248153c62c4Sdrh int totalSize;
249ce98bba2Sdanielk1977 int nReserve;
250fec00eabSdrh sqlite3_mutex_enter(mem.mutex);
251d677b3d6Sdrh assert( mem.disallow==0 );
252bc73971dSdanielk1977 nReserve = ROUND8(nByte);
253ce98bba2Sdanielk1977 totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
2544a50aac5Sdrh mem.nBacktrace*sizeof(void*) + mem.nTitle;
2554c3645c6Sdrh p = malloc(totalSize);
2564c3645c6Sdrh if( p ){
2574a50aac5Sdrh z = p;
2584a50aac5Sdrh pBt = (void**)&z[mem.nTitle];
2590e6f1546Sdrh pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
2604c3645c6Sdrh pHdr->pNext = 0;
2610e6f1546Sdrh pHdr->pPrev = mem.pLast;
2620e6f1546Sdrh if( mem.pLast ){
2630e6f1546Sdrh mem.pLast->pNext = pHdr;
2644c3645c6Sdrh }else{
2650e6f1546Sdrh mem.pFirst = pHdr;
2664c3645c6Sdrh }
2670e6f1546Sdrh mem.pLast = pHdr;
2684c3645c6Sdrh pHdr->iForeGuard = FOREGUARD;
269107b56e8Sdrh pHdr->eType = MEMTYPE_HEAP;
2700e6f1546Sdrh pHdr->nBacktraceSlots = mem.nBacktrace;
2714a50aac5Sdrh pHdr->nTitle = mem.nTitle;
2720e6f1546Sdrh if( mem.nBacktrace ){
2732f999a67Sdrh void *aAddr[40];
2740e6f1546Sdrh pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
2752f999a67Sdrh memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
2766ab3a2ecSdanielk1977 assert(pBt[0]);
2776f332c18Sdanielk1977 if( mem.xBacktrace ){
2786f332c18Sdanielk1977 mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
2796f332c18Sdanielk1977 }
2804c3645c6Sdrh }else{
2814c3645c6Sdrh pHdr->nBacktrace = 0;
2824c3645c6Sdrh }
2834a50aac5Sdrh if( mem.nTitle ){
2844a50aac5Sdrh memcpy(z, mem.zTitle, mem.nTitle);
2854a50aac5Sdrh }
2864c3645c6Sdrh pHdr->iSize = nByte;
2872abcd58fSdrh adjustStats(nByte, +1);
288153c62c4Sdrh pInt = (int*)&pHdr[1];
289ce98bba2Sdanielk1977 pInt[nReserve/sizeof(int)] = REARGUARD;
29010f864e8Sdrh randomFill((char*)pInt, nByte);
29110f864e8Sdrh memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
2924c3645c6Sdrh p = (void*)pInt;
2934c3645c6Sdrh }
2940e6f1546Sdrh sqlite3_mutex_leave(mem.mutex);
2954c3645c6Sdrh return p;
2964c3645c6Sdrh }
2974c3645c6Sdrh
2984c3645c6Sdrh /*
2994c3645c6Sdrh ** Free memory.
3004c3645c6Sdrh */
sqlite3MemFree(void * pPrior)301fec00eabSdrh static void sqlite3MemFree(void *pPrior){
3024c3645c6Sdrh struct MemBlockHdr *pHdr;
3034c3645c6Sdrh void **pBt;
3044a50aac5Sdrh char *z;
3053b4aae56Sdan assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0
3063b4aae56Sdan || mem.mutex!=0 );
3074c3645c6Sdrh pHdr = sqlite3MemsysGetHeader(pPrior);
3084c3645c6Sdrh pBt = (void**)pHdr;
3094c3645c6Sdrh pBt -= pHdr->nBacktraceSlots;
3106bdec4afSdrh sqlite3_mutex_enter(mem.mutex);
3114c3645c6Sdrh if( pHdr->pPrev ){
3124c3645c6Sdrh assert( pHdr->pPrev->pNext==pHdr );
3134c3645c6Sdrh pHdr->pPrev->pNext = pHdr->pNext;
3144c3645c6Sdrh }else{
3150e6f1546Sdrh assert( mem.pFirst==pHdr );
3160e6f1546Sdrh mem.pFirst = pHdr->pNext;
3174c3645c6Sdrh }
3184c3645c6Sdrh if( pHdr->pNext ){
3194c3645c6Sdrh assert( pHdr->pNext->pPrev==pHdr );
3204c3645c6Sdrh pHdr->pNext->pPrev = pHdr->pPrev;
3214c3645c6Sdrh }else{
3220e6f1546Sdrh assert( mem.pLast==pHdr );
3230e6f1546Sdrh mem.pLast = pHdr->pPrev;
3244c3645c6Sdrh }
3254a50aac5Sdrh z = (char*)pBt;
3264a50aac5Sdrh z -= pHdr->nTitle;
327f6418891Smistachkin adjustStats((int)pHdr->iSize, -1);
32810f864e8Sdrh randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
329f6418891Smistachkin (int)pHdr->iSize + sizeof(int) + pHdr->nTitle);
3304a50aac5Sdrh free(z);
3310e6f1546Sdrh sqlite3_mutex_leave(mem.mutex);
3324c3645c6Sdrh }
3334c3645c6Sdrh
3344c3645c6Sdrh /*
3354c3645c6Sdrh ** Change the size of an existing memory allocation.
3364c3645c6Sdrh **
3374c3645c6Sdrh ** For this debugging implementation, we *always* make a copy of the
3384c3645c6Sdrh ** allocation into a new place in memory. In this way, if the
3394c3645c6Sdrh ** higher level code is using pointer to the old allocation, it is
3404c3645c6Sdrh ** much more likely to break and we are much more liking to find
3414c3645c6Sdrh ** the error.
3424c3645c6Sdrh */
sqlite3MemRealloc(void * pPrior,int nByte)343fec00eabSdrh static void *sqlite3MemRealloc(void *pPrior, int nByte){
3444c3645c6Sdrh struct MemBlockHdr *pOldHdr;
3454c3645c6Sdrh void *pNew;
346d677b3d6Sdrh assert( mem.disallow==0 );
3479f129f46Sdrh assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */
3484c3645c6Sdrh pOldHdr = sqlite3MemsysGetHeader(pPrior);
349fec00eabSdrh pNew = sqlite3MemMalloc(nByte);
3504c3645c6Sdrh if( pNew ){
3513fb4b6dfSmistachkin memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize));
3524c3645c6Sdrh if( nByte>pOldHdr->iSize ){
353f6418891Smistachkin randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
3544c3645c6Sdrh }
355fec00eabSdrh sqlite3MemFree(pPrior);
3564c3645c6Sdrh }
3574c3645c6Sdrh return pNew;
3584c3645c6Sdrh }
3594c3645c6Sdrh
360d1370b6dSdrh /*
361d1370b6dSdrh ** Populate the low-level memory allocation function pointers in
362d1370b6dSdrh ** sqlite3GlobalConfig.m with pointers to the routines in this file.
363d1370b6dSdrh */
sqlite3MemSetDefault(void)364d1370b6dSdrh void sqlite3MemSetDefault(void){
365fec00eabSdrh static const sqlite3_mem_methods defaultMethods = {
366fec00eabSdrh sqlite3MemMalloc,
367fec00eabSdrh sqlite3MemFree,
368fec00eabSdrh sqlite3MemRealloc,
369fec00eabSdrh sqlite3MemSize,
370fec00eabSdrh sqlite3MemRoundup,
371fec00eabSdrh sqlite3MemInit,
372fec00eabSdrh sqlite3MemShutdown,
373fec00eabSdrh 0
374fec00eabSdrh };
375d1370b6dSdrh sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
376fec00eabSdrh }
377fec00eabSdrh
3784c3645c6Sdrh /*
379107b56e8Sdrh ** Set the "type" of an allocation.
380107b56e8Sdrh */
sqlite3MemdebugSetType(void * p,u8 eType)381107b56e8Sdrh void sqlite3MemdebugSetType(void *p, u8 eType){
3829a23d26cSdan if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
383107b56e8Sdrh struct MemBlockHdr *pHdr;
384107b56e8Sdrh pHdr = sqlite3MemsysGetHeader(p);
385107b56e8Sdrh assert( pHdr->iForeGuard==FOREGUARD );
386107b56e8Sdrh pHdr->eType = eType;
387107b56e8Sdrh }
388107b56e8Sdrh }
389107b56e8Sdrh
390107b56e8Sdrh /*
391107b56e8Sdrh ** Return TRUE if the mask of type in eType matches the type of the
392107b56e8Sdrh ** allocation p. Also return true if p==NULL.
393107b56e8Sdrh **
394107b56e8Sdrh ** This routine is designed for use within an assert() statement, to
395107b56e8Sdrh ** verify the type of an allocation. For example:
396107b56e8Sdrh **
397d231aa3aSdrh ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
398107b56e8Sdrh */
sqlite3MemdebugHasType(const void * p,u8 eType)39977978a64Smistachkin int sqlite3MemdebugHasType(const void *p, u8 eType){
400107b56e8Sdrh int rc = 1;
4019a23d26cSdan if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
402107b56e8Sdrh struct MemBlockHdr *pHdr;
403107b56e8Sdrh pHdr = sqlite3MemsysGetHeader(p);
404107b56e8Sdrh assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
405107b56e8Sdrh if( (pHdr->eType&eType)==0 ){
406107b56e8Sdrh rc = 0;
407107b56e8Sdrh }
408107b56e8Sdrh }
409107b56e8Sdrh return rc;
410107b56e8Sdrh }
411107b56e8Sdrh
412174b9a16Sdrh /*
413174b9a16Sdrh ** Return TRUE if the mask of type in eType matches no bits of the type of the
414174b9a16Sdrh ** allocation p. Also return true if p==NULL.
415174b9a16Sdrh **
416174b9a16Sdrh ** This routine is designed for use within an assert() statement, to
417174b9a16Sdrh ** verify the type of an allocation. For example:
418174b9a16Sdrh **
419d231aa3aSdrh ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
420174b9a16Sdrh */
sqlite3MemdebugNoType(const void * p,u8 eType)42177978a64Smistachkin int sqlite3MemdebugNoType(const void *p, u8 eType){
422174b9a16Sdrh int rc = 1;
4239a23d26cSdan if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
424174b9a16Sdrh struct MemBlockHdr *pHdr;
425174b9a16Sdrh pHdr = sqlite3MemsysGetHeader(p);
426174b9a16Sdrh assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
427174b9a16Sdrh if( (pHdr->eType&eType)!=0 ){
428174b9a16Sdrh rc = 0;
429174b9a16Sdrh }
430174b9a16Sdrh }
431174b9a16Sdrh return rc;
432174b9a16Sdrh }
433107b56e8Sdrh
434107b56e8Sdrh /*
4354c3645c6Sdrh ** Set the number of backtrace levels kept for each allocation.
4366d2ab0e4Sdanielk1977 ** A value of zero turns off backtracing. The number is always rounded
4374c3645c6Sdrh ** up to a multiple of 2.
4384c3645c6Sdrh */
sqlite3MemdebugBacktrace(int depth)43949e4fd71Sdrh void sqlite3MemdebugBacktrace(int depth){
4404c3645c6Sdrh if( depth<0 ){ depth = 0; }
4414c3645c6Sdrh if( depth>20 ){ depth = 20; }
4422f999a67Sdrh depth = (depth+1)&0xfe;
4430e6f1546Sdrh mem.nBacktrace = depth;
4444c3645c6Sdrh }
4454c3645c6Sdrh
sqlite3MemdebugBacktraceCallback(void (* xBacktrace)(int,int,void **))4466f332c18Sdanielk1977 void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
4476f332c18Sdanielk1977 mem.xBacktrace = xBacktrace;
4486f332c18Sdanielk1977 }
4496f332c18Sdanielk1977
4504c3645c6Sdrh /*
4514a50aac5Sdrh ** Set the title string for subsequent allocations.
4524a50aac5Sdrh */
sqlite3MemdebugSettitle(const char * zTitle)45349e4fd71Sdrh void sqlite3MemdebugSettitle(const char *zTitle){
454ea678832Sdrh unsigned int n = sqlite3Strlen30(zTitle) + 1;
455fec00eabSdrh sqlite3_mutex_enter(mem.mutex);
4564a50aac5Sdrh if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
4574a50aac5Sdrh memcpy(mem.zTitle, zTitle, n);
4584a50aac5Sdrh mem.zTitle[n] = 0;
459bc73971dSdanielk1977 mem.nTitle = ROUND8(n);
4604a50aac5Sdrh sqlite3_mutex_leave(mem.mutex);
4614a50aac5Sdrh }
4624a50aac5Sdrh
sqlite3MemdebugSync()463dbdc4d49Sdanielk1977 void sqlite3MemdebugSync(){
464dbdc4d49Sdanielk1977 struct MemBlockHdr *pHdr;
465dbdc4d49Sdanielk1977 for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
466dbdc4d49Sdanielk1977 void **pBt = (void**)pHdr;
467dbdc4d49Sdanielk1977 pBt -= pHdr->nBacktraceSlots;
468f6418891Smistachkin mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
469dbdc4d49Sdanielk1977 }
470dbdc4d49Sdanielk1977 }
471dbdc4d49Sdanielk1977
4724a50aac5Sdrh /*
4734c3645c6Sdrh ** Open the file indicated and write a log of all unfreed memory
4744c3645c6Sdrh ** allocations into that log.
4754c3645c6Sdrh */
sqlite3MemdebugDump(const char * zFilename)47649e4fd71Sdrh void sqlite3MemdebugDump(const char *zFilename){
4774c3645c6Sdrh FILE *out;
4784c3645c6Sdrh struct MemBlockHdr *pHdr;
4794c3645c6Sdrh void **pBt;
480d2bb3278Sdrh int i;
4814c3645c6Sdrh out = fopen(zFilename, "w");
4824c3645c6Sdrh if( out==0 ){
4834c3645c6Sdrh fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
4844c3645c6Sdrh zFilename);
4854c3645c6Sdrh return;
4864c3645c6Sdrh }
4870e6f1546Sdrh for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
4884a50aac5Sdrh char *z = (char*)pHdr;
4894a50aac5Sdrh z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
490fab69597Sdrh fprintf(out, "**** %lld bytes at %p from %s ****\n",
491d5499d64Sdrh pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
4924c3645c6Sdrh if( pHdr->nBacktrace ){
4934c3645c6Sdrh fflush(out);
4944c3645c6Sdrh pBt = (void**)pHdr;
4954c3645c6Sdrh pBt -= pHdr->nBacktraceSlots;
4964c3645c6Sdrh backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
4974c3645c6Sdrh fprintf(out, "\n");
4984c3645c6Sdrh }
4994c3645c6Sdrh }
500d2bb3278Sdrh fprintf(out, "COUNTS:\n");
501d2bb3278Sdrh for(i=0; i<NCSIZE-1; i++){
5022abcd58fSdrh if( mem.nAlloc[i] ){
5032abcd58fSdrh fprintf(out, " %5d: %10d %10d %10d\n",
5042abcd58fSdrh i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
505d2bb3278Sdrh }
506d2bb3278Sdrh }
5072abcd58fSdrh if( mem.nAlloc[NCSIZE-1] ){
5082abcd58fSdrh fprintf(out, " %5d: %10d %10d %10d\n",
5092abcd58fSdrh NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
5102abcd58fSdrh mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
511d2bb3278Sdrh }
5124c3645c6Sdrh fclose(out);
5134c3645c6Sdrh }
5144c3645c6Sdrh
515a7a8e14bSdanielk1977 /*
516fec00eabSdrh ** Return the number of times sqlite3MemMalloc() has been called.
517a7a8e14bSdanielk1977 */
sqlite3MemdebugMallocCount()51849e4fd71Sdrh int sqlite3MemdebugMallocCount(){
519a7a8e14bSdanielk1977 int i;
520a7a8e14bSdanielk1977 int nTotal = 0;
521a7a8e14bSdanielk1977 for(i=0; i<NCSIZE; i++){
5222abcd58fSdrh nTotal += mem.nAlloc[i];
523a7a8e14bSdanielk1977 }
524a7a8e14bSdanielk1977 return nTotal;
525a7a8e14bSdanielk1977 }
526a7a8e14bSdanielk1977
527d677b3d6Sdrh
5280d18020bSdrh #endif /* SQLITE_MEMDEBUG */
529