| Index: third_party/sqlite/src/src/mem2.c
|
| diff --git a/third_party/sqlite/src/src/mem2.c b/third_party/sqlite/src/src/mem2.c
|
| index 8c498a2abd562f4639a4faaa17652239ff21da74..26448ea8aae0366af0541afea4790b42f4a69b5a 100644
|
| --- a/third_party/sqlite/src/src/mem2.c
|
| +++ b/third_party/sqlite/src/src/mem2.c
|
| @@ -18,8 +18,6 @@
|
| **
|
| ** This file contains implementations of the low-level memory allocation
|
| ** routines specified in the sqlite3_mem_methods object.
|
| -**
|
| -** $Id: mem2.c,v 1.45 2009/03/23 04:33:33 danielk1977 Exp $
|
| */
|
| #include "sqliteInt.h"
|
|
|
| @@ -59,7 +57,8 @@ struct MemBlockHdr {
|
| struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */
|
| char nBacktrace; /* Number of backtraces on this alloc */
|
| char nBacktraceSlots; /* Available backtrace slots */
|
| - short nTitle; /* Bytes of title; includes '\0' */
|
| + u8 nTitle; /* Bytes of title; includes '\0' */
|
| + u8 eType; /* Allocation type code */
|
| int iForeGuard; /* Guard word for sanity */
|
| };
|
|
|
| @@ -213,6 +212,31 @@ static int sqlite3MemRoundup(int n){
|
| }
|
|
|
| /*
|
| +** Fill a buffer with pseudo-random bytes. This is used to preset
|
| +** the content of a new memory allocation to unpredictable values and
|
| +** to clear the content of a freed allocation to unpredictable values.
|
| +*/
|
| +static void randomFill(char *pBuf, int nByte){
|
| + unsigned int x, y, r;
|
| + x = SQLITE_PTR_TO_INT(pBuf);
|
| + y = nByte | 1;
|
| + while( nByte >= 4 ){
|
| + x = (x>>1) ^ (-(x&1) & 0xd0000001);
|
| + y = y*1103515245 + 12345;
|
| + r = x ^ y;
|
| + *(int*)pBuf = r;
|
| + pBuf += 4;
|
| + nByte -= 4;
|
| + }
|
| + while( nByte-- > 0 ){
|
| + x = (x>>1) ^ (-(x&1) & 0xd0000001);
|
| + y = y*1103515245 + 12345;
|
| + r = x ^ y;
|
| + *(pBuf++) = r & 0xff;
|
| + }
|
| +}
|
| +
|
| +/*
|
| ** Allocate nByte bytes of memory.
|
| */
|
| static void *sqlite3MemMalloc(int nByte){
|
| @@ -242,6 +266,7 @@ static void *sqlite3MemMalloc(int nByte){
|
| }
|
| mem.pLast = pHdr;
|
| pHdr->iForeGuard = FOREGUARD;
|
| + pHdr->eType = MEMTYPE_HEAP;
|
| pHdr->nBacktraceSlots = mem.nBacktrace;
|
| pHdr->nTitle = mem.nTitle;
|
| if( mem.nBacktrace ){
|
| @@ -262,7 +287,8 @@ static void *sqlite3MemMalloc(int nByte){
|
| adjustStats(nByte, +1);
|
| pInt = (int*)&pHdr[1];
|
| pInt[nReserve/sizeof(int)] = REARGUARD;
|
| - memset(pInt, 0x65, nReserve);
|
| + randomFill((char*)pInt, nByte);
|
| + memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
|
| p = (void*)pInt;
|
| }
|
| sqlite3_mutex_leave(mem.mutex);
|
| @@ -276,7 +302,8 @@ static void sqlite3MemFree(void *pPrior){
|
| struct MemBlockHdr *pHdr;
|
| void **pBt;
|
| char *z;
|
| - assert( sqlite3GlobalConfig.bMemstat || mem.mutex!=0 );
|
| + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0
|
| + || mem.mutex!=0 );
|
| pHdr = sqlite3MemsysGetHeader(pPrior);
|
| pBt = (void**)pHdr;
|
| pBt -= pHdr->nBacktraceSlots;
|
| @@ -298,8 +325,8 @@ static void sqlite3MemFree(void *pPrior){
|
| z = (char*)pBt;
|
| z -= pHdr->nTitle;
|
| adjustStats(pHdr->iSize, -1);
|
| - memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
|
| - pHdr->iSize + sizeof(int) + pHdr->nTitle);
|
| + randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
|
| + pHdr->iSize + sizeof(int) + pHdr->nTitle);
|
| free(z);
|
| sqlite3_mutex_leave(mem.mutex);
|
| }
|
| @@ -317,12 +344,13 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
|
| struct MemBlockHdr *pOldHdr;
|
| void *pNew;
|
| assert( mem.disallow==0 );
|
| + assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */
|
| pOldHdr = sqlite3MemsysGetHeader(pPrior);
|
| pNew = sqlite3MemMalloc(nByte);
|
| if( pNew ){
|
| memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
|
| if( nByte>pOldHdr->iSize ){
|
| - memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize);
|
| + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
|
| }
|
| sqlite3MemFree(pPrior);
|
| }
|
| @@ -348,6 +376,62 @@ void sqlite3MemSetDefault(void){
|
| }
|
|
|
| /*
|
| +** Set the "type" of an allocation.
|
| +*/
|
| +void sqlite3MemdebugSetType(void *p, u8 eType){
|
| + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
|
| + struct MemBlockHdr *pHdr;
|
| + pHdr = sqlite3MemsysGetHeader(p);
|
| + assert( pHdr->iForeGuard==FOREGUARD );
|
| + pHdr->eType = eType;
|
| + }
|
| +}
|
| +
|
| +/*
|
| +** Return TRUE if the mask of type in eType matches the type of the
|
| +** allocation p. Also return true if p==NULL.
|
| +**
|
| +** This routine is designed for use within an assert() statement, to
|
| +** verify the type of an allocation. For example:
|
| +**
|
| +** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
|
| +*/
|
| +int sqlite3MemdebugHasType(void *p, u8 eType){
|
| + int rc = 1;
|
| + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
|
| + struct MemBlockHdr *pHdr;
|
| + pHdr = sqlite3MemsysGetHeader(p);
|
| + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
|
| + if( (pHdr->eType&eType)==0 ){
|
| + rc = 0;
|
| + }
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| +** Return TRUE if the mask of type in eType matches no bits of the type of the
|
| +** allocation p. Also return true if p==NULL.
|
| +**
|
| +** This routine is designed for use within an assert() statement, to
|
| +** verify the type of an allocation. For example:
|
| +**
|
| +** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
|
| +*/
|
| +int sqlite3MemdebugNoType(void *p, u8 eType){
|
| + int rc = 1;
|
| + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
|
| + struct MemBlockHdr *pHdr;
|
| + pHdr = sqlite3MemsysGetHeader(p);
|
| + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
|
| + if( (pHdr->eType&eType)!=0 ){
|
| + rc = 0;
|
| + }
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| ** Set the number of backtrace levels kept for each allocation.
|
| ** A value of zero turns off backtracing. The number is always rounded
|
| ** up to a multiple of 2.
|
|
|