1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Add some more logging to the malloc system used when SQLITE_MEMDEBUG is defined. (CVS 4901)

FossilOrigin-Name: 79738f582fbac87f2d335e0c6b7f53e3054b41ba
This commit is contained in:
danielk1977
2008-03-21 14:22:44 +00:00
parent f47ce56c49
commit 6f332c18d9
5 changed files with 229 additions and 13 deletions

View File

@@ -13,7 +13,7 @@
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.17 2008/03/18 13:01:38 drh Exp $
** $Id: test_malloc.c,v 1.18 2008/03/21 14:22:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -507,6 +507,130 @@ static int test_memdebug_settitle(
return TCL_OK;
}
#define MALLOC_LOG_FRAMES 5
static Tcl_HashTable aMallocLog;
static int mallocLogEnabled = 0;
typedef struct MallocLog MallocLog;
struct MallocLog {
int nCall;
int nByte;
};
static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
if( mallocLogEnabled ){
MallocLog *pLog;
Tcl_HashEntry *pEntry;
int isNew;
int aKey[MALLOC_LOG_FRAMES];
int nKey = sizeof(int)*MALLOC_LOG_FRAMES;
memset(aKey, 0, nKey);
if( (sizeof(void*)*nFrame)<nKey ){
nKey = nFrame*sizeof(void*);
}
memcpy(aKey, aFrame, nKey);
pEntry = Tcl_CreateHashEntry(&aMallocLog, (const char *)aKey, &isNew);
if( isNew ){
pLog = (MallocLog *)Tcl_Alloc(sizeof(MallocLog));
memset(pLog, 0, sizeof(MallocLog));
Tcl_SetHashValue(pEntry, (ClientData)pLog);
}else{
pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
}
pLog->nCall++;
pLog->nByte += nByte;
}
}
static int test_memdebug_log(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
static int isInit = 0;
int iSub;
enum MB_enum { MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR };
static const char *MB_strs[] = { "start", "stop", "dump", "clear" };
if( !isInit ){
#ifdef SQLITE_MEMDEBUG
extern void sqlite3MemdebugBacktraceCallback(
void (*xBacktrace)(int, int, void **));
sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
#endif
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES);
isInit = 1;
}
if( objc<2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
}
if( Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, &iSub) ){
return TCL_ERROR;
}
switch( (enum MB_enum)iSub ){
case MB_LOG_START:
mallocLogEnabled = 1;
break;
case MB_LOG_STOP:
mallocLogEnabled = 0;
break;
case MB_LOG_DUMP: {
Tcl_HashSearch search;
Tcl_HashEntry *pEntry;
Tcl_Obj *pRet = Tcl_NewObj();
assert(sizeof(int)==sizeof(void*));
for(
pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
pEntry;
pEntry=Tcl_NextHashEntry(&search)
){
Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
int *aKey = (int *)Tcl_GetHashKey(&aMallocLog, pEntry);
int ii;
apElem[0] = Tcl_NewIntObj(pLog->nCall);
apElem[1] = Tcl_NewIntObj(pLog->nByte);
for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
apElem[ii+2] = Tcl_NewIntObj(aKey[ii]);
}
Tcl_ListObjAppendElement(interp, pRet,
Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem)
);
}
Tcl_SetObjResult(interp, pRet);
break;
}
case MB_LOG_CLEAR: {
Tcl_HashSearch search;
Tcl_HashEntry *pEntry;
for(
pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
pEntry;
pEntry=Tcl_NextHashEntry(&search)
){
MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
Tcl_Free((char *)pLog);
}
Tcl_DeleteHashTable(&aMallocLog);
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES);
}
}
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
@@ -529,6 +653,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_memdebug_pending", test_memdebug_pending },
{ "sqlite3_memdebug_settitle", test_memdebug_settitle },
{ "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count },
{ "sqlite3_memdebug_log", test_memdebug_log },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){