Commit 9e5ec9a5 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi

Merge bk-internal.mysql.com:/home/bk/mysql-4.0

into narttu.mysql.fi:/my/mysql-4.0
parents 977c66b4 ecdb1c76
...@@ -138,7 +138,7 @@ extern int NEAR my_errno; /* Last error in mysys */ ...@@ -138,7 +138,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define QUICK_SAFEMALLOC sf_malloc_quick=1 #define QUICK_SAFEMALLOC sf_malloc_quick=1
#define NORMAL_SAFEMALLOC sf_malloc_quick=0 #define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick; extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
extern ulonglong safemalloc_mem_limit; extern ulonglong sf_malloc_mem_limit;
#define CALLER_INFO_PROTO , const char *sFile, uint uLine #define CALLER_INFO_PROTO , const char *sFile, uint uLine
#define CALLER_INFO , __FILE__, __LINE__ #define CALLER_INFO , __FILE__, __LINE__
...@@ -239,7 +239,7 @@ extern int NEAR my_umask, /* Default creation mask */ ...@@ -239,7 +239,7 @@ extern int NEAR my_umask, /* Default creation mask */
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */ NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
NEAR my_dont_interrupt; /* call remember_intr when set */ NEAR my_dont_interrupt; /* call remember_intr when set */
extern my_bool NEAR mysys_uses_curses, my_use_symdir; extern my_bool NEAR mysys_uses_curses, my_use_symdir;
extern long lCurMemory,lMaxMemory; /* from safemalloc */ extern ulong sf_malloc_cur_memory, sf_malloc_max_memory;
extern ulong my_default_record_cache_size; extern ulong my_default_record_cache_size;
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io, extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
......
...@@ -33,8 +33,6 @@ ...@@ -33,8 +33,6 @@
** --print-defaults ; Print the modified command line and exit ** --print-defaults ; Print the modified command line and exit
****************************************************************************/ ****************************************************************************/
#undef SAFEMALLOC /* safe_malloc is not yet initailized */
#include "mysys_priv.h" #include "mysys_priv.h"
#include "m_string.h" #include "m_string.h"
#include "m_ctype.h" #include "m_ctype.h"
......
...@@ -69,14 +69,13 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */ ...@@ -69,14 +69,13 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */
sf_malloc_endhunc=0, /* dump when malloc-message.... */ sf_malloc_endhunc=0, /* dump when malloc-message.... */
/* set theese to 64 or 128 */ /* set theese to 64 or 128 */
sf_malloc_quick=0; /* set if no calls to sanity */ sf_malloc_quick=0; /* set if no calls to sanity */
long lCurMemory = 0L; /* Current memory usage */ ulong sf_malloc_cur_memory= 0L; /* Current memory usage */
long lMaxMemory = 0L; /* Maximum memory usage */ ulong sf_malloc_max_memory= 0L; /* Maximum memory usage */
uint cNewCount = 0; /* Number of times NEW() was called */ uint sf_malloc_count= 0; /* Number of times NEW() was called */
byte *sf_min_adress= (byte*) ~(unsigned long) 0L, byte *sf_min_adress= (byte*) ~(unsigned long) 0L,
*sf_max_adress= (byte*) 0L; *sf_max_adress= (byte*) 0L;
/* Root of the linked list of struct st_irem */
/* Root of the linked list of remembers */ struct st_irem *sf_malloc_root = NULL;
struct remember *pRememberRoot = NULL;
/* from my_alarm */ /* from my_alarm */
int volatile my_have_got_alarm=0; /* declare variable to reset */ int volatile my_have_got_alarm=0; /* declare variable to reset */
......
...@@ -33,27 +33,23 @@ struct st_remember { ...@@ -33,27 +33,23 @@ struct st_remember {
}; };
/* /*
The size of the following structure MUST be dividable by 8 to not cause Structure that stores information of a allocated memory block
alignment problems on some cpu's The data is at &struct_adr+sizeof(ALIGN_SIZE(sizeof(struct irem)))
The lspecialvalue is at the previous 4 bytes from this, which may not
necessarily be in the struct if the struct size isn't aligned at a 8 byte
boundary.
*/ */
struct irem struct st_irem
{ {
struct remember *_pNext; /* Linked list of structures */ struct st_irem *next; /* Linked list of structures */
struct remember *_pPrev; /* Other link */ struct st_irem *prev; /* Other link */
char *_sFileName; /* File in which memory was new'ed */ char *filename; /* File in which memory was new'ed */
uint32 _uLineNum; /* Line number in above file */ uint32 linenum; /* Line number in above file */
uint32 _uDataSize; /* Size requested */ uint32 datasize; /* Size requested */
#if SIZEOF_CHARP == 8 uint32 SpecialValue; /* Underrun marker value */
long _filler; /* For alignment */
#endif
long _lSpecialValue; /* Underrun marker value */
}; };
struct remember {
struct irem tInt;
char aData[1];
};
extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN]; extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN];
...@@ -70,8 +66,8 @@ extern int _my_tempnam_used; ...@@ -70,8 +66,8 @@ extern int _my_tempnam_used;
#endif #endif
extern byte *sf_min_adress,*sf_max_adress; extern byte *sf_min_adress,*sf_max_adress;
extern uint cNewCount; extern uint sf_malloc_count;
extern struct remember *pRememberRoot; extern struct st_irem *sf_malloc_root;
#if defined(THREAD) && !defined(__WIN__) #if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */ extern sigset_t my_signals; /* signals blocked by mf_brkhant */
......
/* Copyright (C) 2000 MySQL AB /* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -69,22 +69,15 @@ ...@@ -69,22 +69,15 @@
#include "my_static.h" #include "my_static.h"
#include "mysys_err.h" #include "mysys_err.h"
ulonglong safemalloc_mem_limit = ~(ulonglong)0; ulonglong sf_malloc_mem_limit= ~(ulonglong)0;
#define pNext tInt._pNext
#define pPrev tInt._pPrev
#define sFileName tInt._sFileName
#define uLineNum tInt._uLineNum
#define uDataSize tInt._uDataSize
#define lSpecialValue tInt._lSpecialValue
#ifndef PEDANTIC_SAFEMALLOC #ifndef PEDANTIC_SAFEMALLOC
/* /*
Set to 1 after TERMINATE() if we had to fiddle with cNewCount and Set to 1 after TERMINATE() if we had to fiddle with sf_malloc_count and
the linked list of blocks so that _sanity() will not fuss when it the linked list of blocks so that _sanity() will not fuss when it
is not supposed to is not supposed to
*/ */
static int sf_malloc_tampered = 0; static int sf_malloc_tampered= 0;
#endif #endif
...@@ -92,11 +85,11 @@ static int sf_malloc_tampered = 0; ...@@ -92,11 +85,11 @@ static int sf_malloc_tampered = 0;
static int check_ptr(const char *where, byte *ptr, const char *sFile, static int check_ptr(const char *where, byte *ptr, const char *sFile,
uint uLine); uint uLine);
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); static int _checkchunk(struct st_irem *pRec, const char *sFile, uint uLine);
/* /*
Note: both these refer to the NEW'ed data only. They do not include Note: We only fill up the allocated block. This do not include
malloc() roundoff or the extra space required by the remember malloc() roundoff or the extra space required by the irem
structures. structures.
*/ */
...@@ -127,218 +120,211 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); ...@@ -127,218 +120,211 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/* Allocate some memory. */ /* Allocate some memory. */
gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) gptr _mymalloc(uint size, const char *filename, uint lineno, myf MyFlags)
{ {
struct remember *pTmp; struct st_irem *irem;
DBUG_ENTER("_mymalloc"); char *data;
DBUG_PRINT("enter",("Size: %u",uSize)); DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",size));
if (!sf_malloc_quick) if (!sf_malloc_quick)
(void) _sanity (sFile, uLine); (void) _sanity (filename, lineno);
if (uSize + lCurMemory > safemalloc_mem_limit) if (size + sf_malloc_cur_memory > sf_malloc_mem_limit)
pTmp = 0; irem= 0;
else else
{ {
/* Allocate the physical memory */ /* Allocate the physical memory */
pTmp = (struct remember *) malloc ( irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) +
ALIGN_SIZE(sizeof(struct irem)) /* remember data */ sf_malloc_prehunc +
+ sf_malloc_prehunc size + /* size requested */
+ uSize /* size requested */ 4 + /* overrun mark */
+ 4 /* overrun mark */ sf_malloc_endhunc);
+ sf_malloc_endhunc }
); /* Check if there isn't anymore memory avaiable */
} if (!irem)
/* Check if there isn't anymore memory avaiable */ {
if (pTmp == NULL) if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{ {
if (MyFlags & MY_FAE) char buff[SC_MAXWIDTH];
error_handler_hook=fatal_error_handler_hook; my_errno=errno;
if (MyFlags & (MY_FAE+MY_WME)) sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename);
{ my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
char buff[SC_MAXWIDTH]; sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
my_errno=errno; size, (size + 1023L) / 1024L,
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
uSize, (uSize + 1023L) / 1024L,
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
} }
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
sf_malloc_max_memory,lineno, filename));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) 0);
}
/* Fill up the structure */ /* Fill up the structure */
*((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY; data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0; sf_malloc_prehunc);
pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1; *((uint32*) (data-sizeof(uint32)))= MAGICKEY;
pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2; data[size + 0]= MAGICEND0;
pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3; data[size + 1]= MAGICEND1;
pTmp -> sFileName = (my_string) sFile; data[size + 2]= MAGICEND2;
pTmp -> uLineNum = uLine; data[size + 3]= MAGICEND3;
pTmp -> uDataSize = uSize; irem->filename= (my_string) filename;
pTmp -> pPrev = NULL; irem->linenum= lineno;
irem->datasize= size;
/* Add this remember structure to the linked list */ irem->prev= NULL;
pthread_mutex_lock(&THR_LOCK_malloc);
if ((pTmp->pNext=pRememberRoot)) /* Add this remember structure to the linked list */
{ pthread_mutex_lock(&THR_LOCK_malloc);
pRememberRoot -> pPrev = pTmp; if ((irem->next= sf_malloc_root))
} sf_malloc_root->prev= irem;
pRememberRoot = pTmp; sf_malloc_root= irem;
/* Keep the statistics */
sf_malloc_cur_memory+= size;
if (sf_malloc_cur_memory > sf_malloc_max_memory)
sf_malloc_max_memory= sf_malloc_cur_memory;
sf_malloc_count++;
pthread_mutex_unlock(&THR_LOCK_malloc);
/* Keep the statistics */ /* Set the memory to the aribtrary wierd value */
lCurMemory += uSize; if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
if (lCurMemory > lMaxMemory) { bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
lMaxMemory = lCurMemory; /* Return a pointer to the real data */
} DBUG_PRINT("exit",("ptr: %lx", data));
cNewCount++; if (sf_min_adress > data)
pthread_mutex_unlock(&THR_LOCK_malloc); sf_min_adress= data;
if (sf_max_adress < data)
/* Set the memory to the aribtrary wierd value */ sf_max_adress= data;
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) DBUG_RETURN ((gptr) data);
bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
(char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
if (sf_min_adress > &(pTmp -> aData[sf_malloc_prehunc]))
sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
if (sf_max_adress < &(pTmp -> aData[sf_malloc_prehunc]))
sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
} }
/* /*
Allocate some new memory and move old memoryblock there. Allocate some new memory and move old memoryblock there.
Free then old memoryblock Free then old memoryblock
*/ */
gptr _myrealloc (register gptr pPtr, register uint uSize, gptr _myrealloc(register gptr ptr, register uint size,
const char *sFile, uint uLine, myf MyFlags) const char *filename, uint lineno, myf MyFlags)
{ {
struct remember *pRec; struct st_irem *irem;
gptr ptr; char *data;
DBUG_ENTER("_myrealloc"); DBUG_ENTER("_myrealloc");
if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR)) if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags)); DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));
if (!sf_malloc_quick) if (!sf_malloc_quick)
(void) _sanity (sFile, uLine); (void) _sanity (filename, lineno);
if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine)) if (check_ptr("Reallocating", (byte*) ptr, filename, lineno))
DBUG_RETURN((gptr) NULL); DBUG_RETURN((gptr) NULL);
pRec = (struct remember *) ((char*) pPtr - ALIGN_SIZE(sizeof(struct irem))- irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))-
sf_malloc_prehunc); sf_malloc_prehunc);
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY)
!= MAGICKEY)
{ {
fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n", fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
uLine, sFile); lineno, filename);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'", DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
uLine, sFile)); lineno, filename));
(void) fflush(stderr); (void) fflush(stderr);
DBUG_RETURN((gptr) NULL); DBUG_RETURN((gptr) NULL);
} }
if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
{ {
uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */ size=min(size, irem->datasize); /* Move as much as possibly */
memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */ memcpy((byte*) data, ptr, (size_t) size); /* Copy old data */
_myfree(pPtr,sFile,uLine,0); /* Free not needed area */ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
} }
else else
{ {
if (MyFlags & MY_HOLD_ON_ERROR) if (MyFlags & MY_HOLD_ON_ERROR)
DBUG_RETURN(pPtr); DBUG_RETURN(ptr);
if (MyFlags & MY_FREE_ON_ERROR) if (MyFlags & MY_FREE_ON_ERROR)
_myfree(pPtr,sFile,uLine,0); _myfree(ptr, filename, lineno, 0);
} }
DBUG_RETURN(ptr); DBUG_RETURN(data);
} /* _myrealloc */ } /* _myrealloc */
/* Deallocate some memory. */ /* Deallocate some memory. */
void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) void _myfree(gptr ptr, const char *filename, uint lineno, myf myflags)
{ {
struct remember *pRec; struct st_irem *irem;
DBUG_ENTER("_myfree"); DBUG_ENTER("_myfree");
DBUG_PRINT("enter",("ptr: %lx",pPtr)); DBUG_PRINT("enter",("ptr: %lx", ptr));
if (!sf_malloc_quick) if (!sf_malloc_quick)
(void) _sanity (sFile, uLine); (void) _sanity (filename, lineno);
if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) || if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) ||
check_ptr("Freeing",(byte*) pPtr,sFile,uLine)) check_ptr("Freeing",(byte*) ptr,filename,lineno))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
/* Calculate the address of the remember structure */ /* Calculate the address of the remember structure */
pRec = (struct remember *) ((byte*) pPtr- ALIGN_SIZE(sizeof(struct irem))- irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))-
sf_malloc_prehunc); sf_malloc_prehunc);
/* /*
Check to make sure that we have a real remember structure. Check to make sure that we have a real remember structure.
Note: this test could fail for four reasons: Note: this test could fail for four reasons:
(1) The memory was already free'ed (1) The memory was already free'ed
(2) The memory was never new'ed (2) The memory was never new'ed
(3) There was an underrun (3) There was an underrun
(4) A stray pointer hit this location (4) A stray pointer hit this location
*/ */
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY)
!= MAGICKEY)
{ {
fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n", fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
uLine, sFile); lineno, filename);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile)); DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename));
(void) fflush(stderr); (void) fflush(stderr);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Remove this structure from the linked list */ /* Remove this structure from the linked list */
pthread_mutex_lock(&THR_LOCK_malloc); pthread_mutex_lock(&THR_LOCK_malloc);
if (pRec -> pPrev) { if (irem->prev)
pRec -> pPrev -> pNext = pRec -> pNext; irem->prev->next= irem->next;
} else { else
pRememberRoot = pRec -> pNext; sf_malloc_root= irem->next;
}
if (pRec -> pNext) { if (irem->next)
pRec -> pNext -> pPrev = pRec -> pPrev; irem->next->prev= irem->prev;
}
/* Handle the statistics */ /* Handle the statistics */
lCurMemory -= pRec -> uDataSize; sf_malloc_cur_memory-= irem->datasize;
cNewCount--; sf_malloc_count--;
pthread_mutex_unlock(&THR_LOCK_malloc); pthread_mutex_unlock(&THR_LOCK_malloc);
#ifndef HAVE_purify #ifndef HAVE_purify
/* Mark this data as free'ed */ /* Mark this data as free'ed */
if (!sf_malloc_quick) if (!sf_malloc_quick)
bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); bfill(ptr, irem->datasize, (pchar) FREE_VAL);
#endif #endif
*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY; *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
/* Actually free the memory */ /* Actually free the memory */
free ((my_string ) pRec); free((char*) irem);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Check if we have a wrong pointer */ /* Check if we have a wrong pointer */
static int check_ptr(const char *where, byte *ptr, const char *sFile, static int check_ptr(const char *where, byte *ptr, const char *filename,
uint uLine) uint lineno)
{ {
if (!ptr) if (!ptr)
{ {
fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n", fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n",
where,uLine, sFile); where,lineno, filename);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile)); DBUG_PRINT("safe",("Null pointer at line %d '%s'", lineno, filename));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
} }
...@@ -346,9 +332,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, ...@@ -346,9 +332,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
if ((long) ptr & (ALIGN_SIZE(1)-1)) if ((long) ptr & (ALIGN_SIZE(1)-1))
{ {
fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n", fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n",
where,uLine, sFile); where,lineno, filename);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'", DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
uLine,sFile)); lineno,filename));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
} }
...@@ -356,9 +342,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, ...@@ -356,9 +342,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
if (ptr < sf_min_adress || ptr > sf_max_adress) if (ptr < sf_min_adress || ptr > sf_max_adress)
{ {
fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n", fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n",
where,uLine, sFile); where,lineno, filename);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'", DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
uLine,sFile)); lineno,filename));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
} }
...@@ -372,9 +358,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, ...@@ -372,9 +358,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
free'ed as well as the statistics. free'ed as well as the statistics.
*/ */
void TERMINATE (FILE *file) void TERMINATE(FILE *file)
{ {
struct remember *pPtr; struct st_irem *irem;
DBUG_ENTER("TERMINATE"); DBUG_ENTER("TERMINATE");
pthread_mutex_lock(&THR_LOCK_malloc); pthread_mutex_lock(&THR_LOCK_malloc);
...@@ -384,14 +370,15 @@ void TERMINATE (FILE *file) ...@@ -384,14 +370,15 @@ void TERMINATE (FILE *file)
NEWs than FREEs. <0, etc. NEWs than FREEs. <0, etc.
*/ */
if (cNewCount) if (sf_malloc_count)
{ {
if (file) if (file)
{ {
fprintf(file, "Warning: Not freed memory segments: %d\n", cNewCount); fprintf(file, "Warning: Not freed memory segments: %d\n",
sf_malloc_count);
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe",("cNewCount: %d",cNewCount)); DBUG_PRINT("safe",("sf_malloc_count: %d", sf_malloc_count));
} }
/* /*
...@@ -399,42 +386,44 @@ void TERMINATE (FILE *file) ...@@ -399,42 +386,44 @@ void TERMINATE (FILE *file)
but not free'ed with FREE. but not free'ed with FREE.
*/ */
if ((pPtr=pRememberRoot)) if ((irem= sf_malloc_root))
{ {
if (file) if (file)
{ {
fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",lCurMemory); fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",
sf_malloc_cur_memory);
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory)); DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",
while (pPtr) sf_malloc_cur_memory));
while (irem)
{ {
char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc);
if (file) if (file)
{ {
fprintf(file, fprintf(file,
"\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'", "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
pPtr -> uDataSize, irem->datasize, (long) data, irem->linenum, irem->filename);
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
fprintf(file, "\n"); fprintf(file, "\n");
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe", DBUG_PRINT("safe",
("%6u bytes at 0x%09lx, allocated at line %4d in '%s'", ("%6u bytes at 0x%09lx, allocated at line %4d in '%s'",
pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]), irem->datasize, data, irem->linenum, irem->filename));
pPtr -> uLineNum, pPtr -> sFileName)); irem= irem->next;
pPtr = pPtr -> pNext;
} }
} }
/* Report the memory usage statistics */ /* Report the memory usage statistics */
if (file) if (file)
{ {
fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n", fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n",
lMaxMemory, (lMaxMemory + 1023L) / 1024L); sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)", DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
lMaxMemory, (lMaxMemory + 1023L) / 1024L)); sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) /
1024L));
pthread_mutex_unlock(&THR_LOCK_malloc); pthread_mutex_unlock(&THR_LOCK_malloc);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -442,44 +431,41 @@ void TERMINATE (FILE *file) ...@@ -442,44 +431,41 @@ void TERMINATE (FILE *file)
/* Returns 0 if chunk is ok */ /* Returns 0 if chunk is ok */
static int _checkchunk (register struct remember *pRec, const char *sFile, static int _checkchunk(register struct st_irem *irem, const char *filename,
uint uLine) uint lineno)
{ {
reg1 uint uSize; int flag=0;
reg2 my_string magicp; char *magicp, *data;
reg3 int flag=0;
data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc);
/* Check for a possible underrun */ /* Check for a possible underrun */
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) if (*((uint32*) (data- sizeof(uint32))) != MAGICKEY)
!= MAGICKEY)
{ {
fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,", fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,",
pRec -> sFileName, pRec -> uLineNum); irem->filename, irem->linenum);
fprintf(stderr, " discovered at %s:%d\n", sFile, uLine); fprintf(stderr, " discovered at %s:%d\n", filename, lineno);
(void) fflush(stderr); (void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d", DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]), data, irem->filename, irem->linenum));
pRec -> sFileName,
pRec -> uLineNum));
flag=1; flag=1;
} }
/* Check for a possible overrun */ /* Check for a possible overrun */
uSize = pRec -> uDataSize; magicp= data + irem->datasize;
magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]);
if (*magicp++ != MAGICEND0 || if (*magicp++ != MAGICEND0 ||
*magicp++ != MAGICEND1 || *magicp++ != MAGICEND1 ||
*magicp++ != MAGICEND2 || *magicp++ != MAGICEND2 ||
*magicp++ != MAGICEND3) *magicp++ != MAGICEND3)
{ {
fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,", fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,",
pRec -> sFileName, pRec -> uLineNum); irem->filename, irem->linenum);
fprintf(stderr, " discovered at '%s:%d'\n", sFile, uLine); fprintf(stderr, " discovered at '%s:%d'\n", filename, lineno);
(void) fflush(stderr); (void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d", DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]), data,
pRec -> sFileName, irem->filename,
pRec -> uLineNum)); irem->linenum));
flag=1; flag=1;
} }
return(flag); return(flag);
...@@ -488,28 +474,28 @@ static int _checkchunk (register struct remember *pRec, const char *sFile, ...@@ -488,28 +474,28 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
/* Returns how many wrong chunks */ /* Returns how many wrong chunks */
int _sanity (const char *sFile, uint uLine) int _sanity(const char *filename, uint lineno)
{ {
reg1 struct remember *pTmp; reg1 struct st_irem *irem;
reg2 int flag=0; reg2 int flag=0;
uint count=0; uint count=0;
pthread_mutex_lock(&THR_LOCK_malloc); pthread_mutex_lock(&THR_LOCK_malloc);
#ifndef PEDANTIC_SAFEMALLOC #ifndef PEDANTIC_SAFEMALLOC
if (sf_malloc_tampered && cNewCount < 0) if (sf_malloc_tampered && sf_malloc_count < 0)
cNewCount=0; sf_malloc_count=0;
#endif #endif
count=cNewCount; count=sf_malloc_count;
for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext) for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next)
flag+=_checkchunk (pTmp, sFile, uLine); flag+= _checkchunk (irem, filename, lineno);
pthread_mutex_unlock(&THR_LOCK_malloc); pthread_mutex_unlock(&THR_LOCK_malloc);
if (count || pTmp) if (count || irem)
{ {
const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'"; const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'";
fprintf(stderr, format, sFile, uLine); fputc('\n',stderr); fprintf(stderr, format, filename, lineno); fputc('\n',stderr);
fprintf(stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp); fprintf(stderr, "root=%p,count=%d,irem=%p\n", sf_malloc_root,count,irem);
(void) fflush(stderr); (void) fflush(stderr);
DBUG_PRINT("safe",(format, sFile, uLine)); DBUG_PRINT("safe",(format, filename, lineno));
flag=1; flag=1;
} }
return flag; return flag;
...@@ -518,33 +504,33 @@ int _sanity (const char *sFile, uint uLine) ...@@ -518,33 +504,33 @@ int _sanity (const char *sFile, uint uLine)
/* malloc and copy */ /* malloc and copy */
gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine, gptr _my_memdup(const byte *from, uint length, const char *filename,
myf MyFlags) uint lineno, myf MyFlags)
{ {
gptr ptr; gptr ptr;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length); memcpy((byte*) ptr, (byte*) from,(size_t) length);
return(ptr); return(ptr);
} /*_my_memdup */ } /*_my_memdup */
char *_my_strdup(const char *from, const char *sFile, uint uLine, char *_my_strdup(const char *from, const char *filename, uint lineno,
myf MyFlags) myf MyFlags)
{ {
gptr ptr; gptr ptr;
uint length=(uint) strlen(from)+1; uint length=(uint) strlen(from)+1;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length); memcpy((byte*) ptr, (byte*) from,(size_t) length);
return((char*) ptr); return((char*) ptr);
} /* _my_strdup */ } /* _my_strdup */
char *_my_strdup_with_length(const byte *from, uint length, char *_my_strdup_with_length(const byte *from, uint length,
const char *sFile, uint uLine, const char *filename, uint lineno,
myf MyFlags) myf MyFlags)
{ {
gptr ptr; gptr ptr;
if ((ptr=_mymalloc(length+1,sFile,uLine,MyFlags)) != 0) if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
{ {
memcpy((byte*) ptr, (byte*) from,(size_t) length); memcpy((byte*) ptr, (byte*) from,(size_t) length);
ptr[length]=0; ptr[length]=0;
......
...@@ -4292,7 +4292,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -4292,7 +4292,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break; break;
case OPT_SAFEMALLOC_MEM_LIMIT: case OPT_SAFEMALLOC_MEM_LIMIT:
#if !defined(DBUG_OFF) && defined(SAFEMALLOC) #if !defined(DBUG_OFF) && defined(SAFEMALLOC)
safemalloc_mem_limit = atoi(argument); sf_malloc_mem_limit = atoi(argument);
#endif #endif
break; break;
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
......
...@@ -1208,9 +1208,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1208,9 +1208,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
opened_tables,refresh_version, cached_tables(), opened_tables,refresh_version, cached_tables(),
uptime ? (float)thd->query_id/(float)uptime : 0); uptime ? (float)thd->query_id/(float)uptime : 0);
#ifdef SAFEMALLOC #ifdef SAFEMALLOC
if (lCurMemory) // Using SAFEMALLOC if (sf_malloc_cur_memory) // Using SAFEMALLOC
sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK", sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK",
(lCurMemory+1023L)/1024L,(lMaxMemory+1023L)/1024L); (sf_malloc_cur_memory+1023L)/1024L,
(sf_malloc_max_memory+1023L)/1024L);
#endif #endif
VOID(my_net_write(net, buff,(uint) strlen(buff))); VOID(my_net_write(net, buff,(uint) strlen(buff)));
VOID(net_flush(net)); VOID(net_flush(net));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment