1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-23 17:33:50 +03:00

memory: Remove memory debugging

This is useless compared to sanitizers or valgrind and has a
considerable performance impact if enabled accidentally.
This commit is contained in:
Nick Wellnhofer 2024-04-28 18:33:40 +02:00
parent 5e80f4381b
commit 1cdfece12b
19 changed files with 142 additions and 716 deletions

View File

@ -37,7 +37,6 @@ option(LIBXML2_WITH_ICU "Add ICU support" OFF)
option(LIBXML2_WITH_ISO8859X "Add ISO8859X support if no iconv" ON)
option(LIBXML2_WITH_LEGACY "Add deprecated APIs for compatibility" OFF)
option(LIBXML2_WITH_LZMA "Use liblzma" OFF)
option(LIBXML2_WITH_MEM_DEBUG "Add the memory debugging module" OFF)
option(LIBXML2_WITH_MODULES "Add the dynamic modules support" ON)
option(LIBXML2_WITH_OUTPUT "Add the serialization support" ON)
option(LIBXML2_WITH_PATTERN "Add the xmlPattern selection interface" ON)
@ -73,7 +72,7 @@ if(LIBXML2_WITH_PYTHON)
CACHE PATH "Python bindings install directory")
endif()
foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_LEGACY WITH_LZMA WITH_MEM_DEBUG WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_SAX1 WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_XPTR_LOCS WITH_ZLIB)
foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_LEGACY WITH_LZMA WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_SAX1 WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_XPTR_LOCS WITH_ZLIB)
if(LIBXML2_${VARIABLE})
set(${VARIABLE} 1)
else()

View File

@ -54,7 +54,6 @@ The following options disable or enable code modules and relevant symbols:
--with-icu ICU support (off)
--with-iso8859x ISO-8859-X support if no iconv (on)
--with-lzma[=DIR] use liblzma in DIR (off)
--with-mem-debug memory debugging module (off)
--with-modules dynamic modules support (on)
--with-output serialization support (on)
--with-pattern xmlPattern selection interface (on)

View File

@ -87,8 +87,6 @@ AC_ARG_WITH(iso8859x,
[ --with-iso8859x ISO-8859-X support if no iconv (on)])
AC_ARG_WITH(lzma,
[ --with-lzma[[=DIR]] use liblzma in DIR (off)])
AC_ARG_WITH(mem_debug,
[ --with-mem-debug memory debugging module (off)])
AC_ARG_WITH(modules,
[ --with-modules dynamic modules support (on)])
AC_ARG_WITH(output,
@ -233,7 +231,6 @@ if test "$with_minimum" = "yes"; then
test "$with_iconv" = "" && with_iconv=no
test "$with_iso8859x" = "" && with_iso8859x=no
test "$with_lzma" = "" && with_lzma=no
test "$with_mem_debug" = "" && with_mem_debug=no
test "$with_output" = "" && with_output=no
test "$with_pattern" = "" && with_pattern=no
test "$with_push" = "" && with_push=no
@ -721,19 +718,6 @@ fi
AC_SUBST(WITH_DEBUG)
AM_CONDITIONAL(WITH_DEBUG_SOURCES, test "$WITH_DEBUG" = "1")
if test "$with_mem_debug" = "yes" ; then
if test "$with_thread_alloc" = "yes" ; then
echo Disabling memory debug - cannot use mem-debug with thread-alloc!
WITH_MEM_DEBUG=0
else
echo Enabling memory debug support
WITH_MEM_DEBUG=1
fi
else
WITH_MEM_DEBUG=0
fi
AC_SUBST(WITH_MEM_DEBUG)
dnl
dnl Check for Python
dnl

View File

@ -2944,15 +2944,6 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
#endif /* LIBXML_OUTPUT_ENABLED */
} else if (!strcmp(command, "grep")) {
xmlShellGrep(ctxt, arg, ctxt->node, NULL);
} else if (!strcmp(command, "free")) {
if (arg[0] == 0) {
xmlMemShow(ctxt->output, 0);
} else {
int len = 0;
sscanf(arg, "%d", &len);
xmlMemShow(ctxt->output, len);
}
} else if (!strcmp(command, "pwd")) {
char dir[500];

View File

@ -731,13 +731,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term><command>free</command></term>
<listitem>
<para>Display memory usage.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>load <replaceable>FILENAME</replaceable></command></term>
<listitem>

View File

@ -175,13 +175,6 @@ static unsigned xmlMainThreadRngState[2];
* Memory allocation routines
*/
#if defined(DEBUG_MEMORY_LOCATION)
xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
#else
/**
* xmlFree:
* @mem: an already allocated block of memory
@ -240,7 +233,6 @@ xmlPosixStrdup(const char *cur) {
* Returns the copy of the string or NULL in case of error
*/
xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup;
#endif /* DEBUG_MEMORY_LOCATION */
/**
* xmlBufferAllocScheme:
@ -777,19 +769,11 @@ xmlInitGlobalState(xmlGlobalStatePtr gs) {
gs->gs_xmlDoValidityCheckingDefaultValue =
xmlDoValidityCheckingDefaultValueThrDef;
#ifdef LIBXML_THREAD_ALLOC_ENABLED
#ifdef DEBUG_MEMORY_LOCATION
gs->gs_xmlFree = xmlMemFree;
gs->gs_xmlMalloc = xmlMemMalloc;
gs->gs_xmlMallocAtomic = xmlMemMalloc;
gs->gs_xmlRealloc = xmlMemRealloc;
gs->gs_xmlMemStrdup = xmlMemoryStrdup;
#else
gs->gs_xmlFree = free;
gs->gs_xmlMalloc = malloc;
gs->gs_xmlMallocAtomic = malloc;
gs->gs_xmlRealloc = realloc;
gs->gs_xmlMemStrdup = xmlPosixStrdup;
#endif
#endif
gs->gs_xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
#ifdef LIBXML_OUTPUT_ENABLED

View File

@ -17,7 +17,6 @@ xmlversion_h.set10('WITH_LEGACY', want_legacy)
xmlversion_h.set10('WITH_LZMA', want_lzma)
xmlversion_h.set10('WITH_MODULES', with_modules)
xmlversion_h.set('MODULE_EXTENSION', module_extension)
xmlversion_h.set10('WITH_MEM_DEBUG', want_mem_debug)
xmlversion_h.set10('WITH_OUTPUT', want_output)
xmlversion_h.set10('WITH_PATTERN', want_pattern)
xmlversion_h.set10('WITH_PUSH', want_push)

View File

@ -147,12 +147,16 @@ XMLPUBFUN int
xmlMemUsed (void);
XMLPUBFUN int
xmlMemBlocks (void);
XML_DEPRECATED
XMLPUBFUN void
xmlMemDisplay (FILE *fp);
XML_DEPRECATED
XMLPUBFUN void
xmlMemDisplayLast(FILE *fp, long nbBytes);
XML_DEPRECATED
XMLPUBFUN void
xmlMemShow (FILE *fp, int nr);
XML_DEPRECATED
XMLPUBFUN void
xmlMemoryDump (void);
XMLPUBFUN void *
@ -163,60 +167,19 @@ XMLPUBFUN void
xmlMemFree (void *ptr);
XMLPUBFUN char *
xmlMemoryStrdup (const char *str);
XML_DEPRECATED
XMLPUBFUN void *
xmlMallocLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XML_DEPRECATED
XMLPUBFUN void *
xmlReallocLoc (void *ptr, size_t size, const char *file, int line);
XML_DEPRECATED
XMLPUBFUN void *
xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XML_DEPRECATED
XMLPUBFUN char *
xmlMemStrdupLoc (const char *str, const char *file, int line);
/** DOC_DISABLE */
#ifdef DEBUG_MEMORY_LOCATION
/**
* xmlMalloc:
* @size: number of bytes to allocate
*
* Wrapper for the malloc() function used in the XML library.
*
* Returns the pointer to the allocated area or NULL in case of error.
*/
#define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__)
/**
* xmlMallocAtomic:
* @size: number of bytes to allocate
*
* Wrapper for the malloc() function used in the XML library for allocation
* of block not containing pointers to other areas.
*
* Returns the pointer to the allocated area or NULL in case of error.
*/
#define xmlMallocAtomic(size) xmlMallocAtomicLoc((size), __FILE__, __LINE__)
/**
* xmlRealloc:
* @ptr: pointer to the existing allocated area
* @size: number of bytes to allocate
*
* Wrapper for the realloc() function used in the XML library.
*
* Returns the pointer to the allocated area or NULL in case of error.
*/
#define xmlRealloc(ptr, size) xmlReallocLoc((ptr), (size), __FILE__, __LINE__)
/**
* xmlMemStrdup:
* @str: pointer to the existing string
*
* Wrapper for the strdup() function, xmlStrdup() is usually preferred.
*
* Returns the pointer to the allocated area or NULL in case of error.
*/
#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
#endif /* DEBUG_MEMORY_LOCATION */
/** DOC_ENABLE */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -262,15 +262,6 @@
#define LIBXML_DEBUG_ENABLED
#endif
/**
* DEBUG_MEMORY_LOCATION:
*
* Whether the memory debugging is configured in
*/
#if @WITH_MEM_DEBUG@
#define DEBUG_MEMORY_LOCATION
#endif
/**
* LIBXML_UNICODE_ENABLED:
*

View File

@ -67,7 +67,6 @@ want_ipv6 = get_option('ipv6')
want_iso8859x = get_option('iso8859x')
want_legacy = get_option('legacy')
want_lzma = get_option('lzma')
want_mem_debug = get_option('mem-debug')
want_modules = get_option('modules')
want_output = get_option('output')
want_pattern = get_option('pattern')
@ -188,7 +187,6 @@ if get_option('minimum')
want_ipv6 = false
want_iso8859x = false
want_lzma = false
want_mem_debug = false
want_modules = false
want_output = false
want_pattern = false
@ -846,7 +844,6 @@ summary(
'iso8859x': want_iso8859x,
'legacy': want_legacy,
'lzma': want_lzma,
'mem-debug': want_mem_debug,
'modules': want_modules,
'output': want_output,
'pattern': want_pattern,

View File

@ -15,7 +15,6 @@
# [X] iso8859x
# [X] legacy
# [X] lzma
# [X] mem-debug
# [X] modules
# [X] output
# [X] pattern
@ -129,12 +128,6 @@ option('lzma',
description: 'LZMA support'
)
option('mem-debug',
type: 'boolean',
value: false,
description: 'Memory debugging module'
)
option('modules',
type: 'boolean',
value: true,

View File

@ -685,11 +685,7 @@ xmlHasFeature(xmlFeature feature)
return(0);
#endif
case XML_WITH_DEBUG_MEM:
#ifdef DEBUG_MEMORY_LOCATION
return(1);
#else
return(0);
#endif
case XML_WITH_ZLIB:
#ifdef LIBXML_ZLIB_ENABLED
return(1);

View File

@ -185,17 +185,6 @@ libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED,
return(Py_None);
}
PyObject *
libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
ATTRIBUTE_UNUSED PyObject * args)
{
if (libxmlMemoryDebug != 0)
xmlMemoryDump();
Py_INCREF(Py_None);
return (Py_None);
}
/************************************************************************
* *
* Handling Python FILE I/O at the C level *

View File

@ -779,6 +779,12 @@ def popInputCallbacks():
if len(__input_callbacks) == 0:
libxml2mod.xmlUnregisterInputCallback()
#
# Deprecated
#
def dumpMemory():
"""DEPRECATED: This feature was removed."""
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
#
# Everything before this line comes from libxml.py

View File

@ -124,10 +124,6 @@
<return type='int' info="returns the number of bytes allocated and not freed"/>
<arg name='activate' type='int' info='1 switch on memory debugging 0 switch it off'/>
</function>
<function name='xmlDumpMemory' file='python'>
<info>dump the memory allocated in the file .memdump</info>
<return type='void'/>
</function>
<!-- xmlNsPtr accessors -->
<function name='xmlNodeGetNs' file='python_accessor'>
<info>Get the namespace of a node</info>

View File

@ -415,7 +415,6 @@ xmlconfTestItem(xmlDocPtr doc, xmlNodePtr cur) {
test_log("test %s : %s leaked %d bytes\n",
id, filename, final - mem);
nb_leaks++;
xmlMemDisplayLast(logfile, final - mem);
}
nb_tests++;

View File

@ -44,7 +44,6 @@ var withIso8859x = false;
var withZlib = false;
var withLzma = false;
var withDebug = true;
var withMemDebug = false;
var withSchemas = true;
var withSchematron = true;
var withRegExps = true;
@ -128,7 +127,6 @@ function usage()
txt += " zlib: Enable zlib support (" + (withZlib? "yes" : "no") + ")\n";
txt += " lzma: Enable lzma support (" + (withLzma? "yes" : "no") + ")\n";
txt += " xml_debug: Enable XML debbugging module (" + (withDebug? "yes" : "no") + ")\n";
txt += " mem_debug: Enable memory debugger (" + (withMemDebug? "yes" : "no") + ")\n";
txt += " regexps: Enable regular expressions (" + (withRegExps? "yes" : "no") + ")\n";
txt += " modules: Enable module support (" + (withModules? "yes" : "no") + ")\n";
txt += " tree: Enable tree api (" + (withTree? "yes" : "no") + ")\n";
@ -223,7 +221,6 @@ function discoverVersion()
vf.WriteLine("WITH_ZLIB=" + (withZlib? "1" : "0"));
vf.WriteLine("WITH_LZMA=" + (withLzma? "1" : "0"));
vf.WriteLine("WITH_DEBUG=" + (withDebug? "1" : "0"));
vf.WriteLine("WITH_MEM_DEBUG=" + (withMemDebug? "1" : "0"));
vf.WriteLine("WITH_SCHEMAS=" + (withSchemas? "1" : "0"));
vf.WriteLine("WITH_SCHEMATRON=" + (withSchematron? "1" : "0"));
vf.WriteLine("WITH_REGEXPS=" + (withRegExps? "1" : "0"));
@ -327,8 +324,6 @@ function configureLibxml()
of.WriteLine(s.replace(/\@WITH_LZMA\@/, withLzma? "1" : "0"));
} else if (s.search(/\@WITH_DEBUG\@/) != -1) {
of.WriteLine(s.replace(/\@WITH_DEBUG\@/, withDebug? "1" : "0"));
} else if (s.search(/\@WITH_MEM_DEBUG\@/) != -1) {
of.WriteLine(s.replace(/\@WITH_MEM_DEBUG\@/, withMemDebug? "1" : "0"));
} else if (s.search(/\@WITH_SCHEMAS\@/) != -1) {
of.WriteLine(s.replace(/\@WITH_SCHEMAS\@/, withSchemas? "1" : "0"));
} else if (s.search(/\@WITH_SCHEMATRON\@/) != -1) {
@ -478,8 +473,6 @@ for (i = 0; (i < WScript.Arguments.length) && (error == 0); i++) {
withLzma = strToBool(arg.substring(opt.length + 1, arg.length));
else if (opt == "xml_debug")
withDebug = strToBool(arg.substring(opt.length + 1, arg.length));
else if (opt == "mem_debug")
withMemDebug = strToBool(arg.substring(opt.length + 1, arg.length));
else if (opt == "schemas")
withSchemas = strToBool(arg.substring(opt.length + 1, arg.length));
else if (opt == "schematron")
@ -656,7 +649,6 @@ txtOut += " iso8859x support: " + boolToStr(withIso8859x) + "\n";
txtOut += " zlib support: " + boolToStr(withZlib) + "\n";
txtOut += " lzma support: " + boolToStr(withLzma) + "\n";
txtOut += " Debugging module: " + boolToStr(withDebug) + "\n";
txtOut += " Memory debugging: " + boolToStr(withMemDebug) + "\n";
txtOut += " Regexp support: " + boolToStr(withRegExps) + "\n";
txtOut += " Module support: " + boolToStr(withModules) + "\n";
txtOut += " Tree support: " + boolToStr(withTree) + "\n";

View File

@ -2987,7 +2987,6 @@ static void showVersion(const char *name) {
if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
fprintf(stderr, "\n");

View File

@ -12,18 +12,6 @@
#include <ctype.h>
#include <time.h>
/**
* MEM_LIST:
*
* keep track of all allocated blocks for error reporting
* Always build the memory list !
*/
#ifdef DEBUG_MEMORY_LOCATION
#ifndef MEM_LIST
#define MEM_LIST /* keep a list of all the allocated memory blocks */
#endif
#endif
#include <libxml/xmlmemory.h>
#include <libxml/xmlerror.h>
#include <libxml/parser.h>
@ -34,62 +22,31 @@
static unsigned long debugMemSize = 0;
static unsigned long debugMemBlocks = 0;
static unsigned long debugMaxMemSize = 0;
static xmlMutex xmlMemMutex;
void xmlMallocBreakpoint(void);
/************************************************************************
* *
* Macros, variables and associated types *
* *
************************************************************************/
#if !defined(LIBXML_THREAD_ENABLED) && !defined(LIBXML_THREAD_ALLOC_ENABLED)
#ifdef xmlMalloc
#undef xmlMalloc
#endif
#ifdef xmlRealloc
#undef xmlRealloc
#endif
#ifdef xmlMemStrdup
#undef xmlMemStrdup
#endif
#endif
/*
* Each of the blocks allocated begin with a header containing information
*/
#define MEMTAG 0x5aa5U
#define MALLOC_TYPE 1
#define REALLOC_TYPE 2
#define STRDUP_TYPE 3
#define MALLOC_ATOMIC_TYPE 4
#define REALLOC_ATOMIC_TYPE 5
typedef struct memnod {
unsigned int mh_tag;
unsigned int mh_type;
unsigned long mh_number;
size_t mh_size;
#ifdef MEM_LIST
struct memnod *mh_next;
struct memnod *mh_prev;
#endif
const char *mh_file;
unsigned int mh_line;
} MEMHDR;
} MEMHDR;
#ifdef SUN4
#define ALIGN_SIZE 16
#else
#define ALIGN_SIZE sizeof(double)
#endif
#define HDR_SIZE sizeof(MEMHDR)
#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
#define RESERVE_SIZE (((sizeof(MEMHDR) + ALIGN_SIZE - 1) \
/ ALIGN_SIZE ) * ALIGN_SIZE)
#define MAX_SIZE_T ((size_t)-1)
@ -97,102 +54,21 @@ typedef struct memnod {
#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE))
#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
static unsigned int block=0;
static unsigned int xmlMemStopAtBlock = 0;
static void *xmlMemTraceBlockAt = NULL;
#ifdef MEM_LIST
static MEMHDR *memlist = NULL;
#endif
static void debugmem_tag_error(void *addr);
#ifdef MEM_LIST
static void debugmem_list_add(MEMHDR *);
static void debugmem_list_delete(MEMHDR *);
#endif
#define Mem_Tag_Err(a) debugmem_tag_error(a);
#ifndef TEST_POINT
#define TEST_POINT
#endif
/**
* xmlMallocBreakpoint:
*
* Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
* number reaches the specified value this function is called. One need to add a breakpoint
* to it to get the context in which the given block is allocated.
*/
void
xmlMallocBreakpoint(void) {
fprintf(stderr,
"xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
}
/**
* xmlMallocLoc:
* @size: an int specifying the size in byte to allocate.
* @file: the file name or NULL
* @line: the line number
*
* a malloc() equivalent, with logging of the allocation info.
* DEPRECATED: don't use
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
xmlMallocLoc(size_t size, const char * file, int line)
xmlMallocLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED)
{
MEMHDR *p;
void *ret;
xmlInitParser();
TEST_POINT
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr,
"xmlMallocLoc : Unsigned overflow\n");
return(NULL);
}
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
if (!p) {
fprintf(stderr,
"xmlMallocLoc : Out of free space\n");
return(NULL);
}
p->mh_tag = MEMTAG;
p->mh_size = size;
p->mh_type = MALLOC_TYPE;
p->mh_file = file;
p->mh_line = line;
xmlMutexLock(&xmlMemMutex);
p->mh_number = ++block;
debugMemSize += size;
debugMemBlocks++;
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
debugmem_list_add(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
ret = HDR_2_CLIENT(p);
if (xmlMemTraceBlockAt == ret) {
fprintf(stderr,
"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
(long unsigned)size);
xmlMallocBreakpoint();
}
TEST_POINT
return(ret);
return(xmlMemMalloc(size));
}
/**
@ -201,64 +77,17 @@ xmlMallocLoc(size_t size, const char * file, int line)
* @file: the file name or NULL
* @line: the line number
*
* a malloc() equivalent, with logging of the allocation info.
* DEPRECATED: don't use
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
xmlMallocAtomicLoc(size_t size, const char * file, int line)
xmlMallocAtomicLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED)
{
MEMHDR *p;
void *ret;
xmlInitParser();
TEST_POINT
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr,
"xmlMallocAtomicLoc : Unsigned overflow\n");
return(NULL);
}
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
if (!p) {
fprintf(stderr,
"xmlMallocAtomicLoc : Out of free space\n");
return(NULL);
}
p->mh_tag = MEMTAG;
p->mh_size = size;
p->mh_type = MALLOC_ATOMIC_TYPE;
p->mh_file = file;
p->mh_line = line;
xmlMutexLock(&xmlMemMutex);
p->mh_number = ++block;
debugMemSize += size;
debugMemBlocks++;
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
debugmem_list_add(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
ret = HDR_2_CLIENT(p);
if (xmlMemTraceBlockAt == ret) {
fprintf(stderr,
"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
(long unsigned)size);
xmlMallocBreakpoint();
}
TEST_POINT
return(ret);
return(xmlMemMalloc(size));
}
/**
* xmlMemMalloc:
* @size: an int specifying the size in byte to allocate.
@ -267,11 +96,32 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
xmlMemMalloc(size_t size)
{
return(xmlMallocLoc(size, "none", 0));
MEMHDR *p;
xmlInitParser();
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr, "xmlMemMalloc: Unsigned overflow\n");
return(NULL);
}
p = (MEMHDR *) malloc(RESERVE_SIZE + size);
if (!p) {
fprintf(stderr, "xmlMemMalloc: Out of memory\n");
return(NULL);
}
p->mh_tag = MEMTAG;
p->mh_size = size;
xmlMutexLock(&xmlMemMutex);
debugMemSize += size;
debugMemBlocks++;
xmlMutexUnlock(&xmlMemMutex);
return(HDR_2_CLIENT(p));
}
/**
@ -281,79 +131,15 @@ xmlMemMalloc(size_t size)
* @file: the file name or NULL
* @line: the line number
*
* a realloc() equivalent, with logging of the allocation info.
* DEPRECATED: don't use
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
xmlReallocLoc(void *ptr, size_t size, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED)
{
MEMHDR *p, *tmp;
unsigned long number;
if (ptr == NULL)
return(xmlMallocLoc(size, file, line));
xmlInitParser();
TEST_POINT
p = CLIENT_2_HDR(ptr);
number = p->mh_number;
if (xmlMemStopAtBlock == number) xmlMallocBreakpoint();
if (p->mh_tag != MEMTAG) {
Mem_Tag_Err(p);
goto error;
}
p->mh_tag = ~MEMTAG;
xmlMutexLock(&xmlMemMutex);
debugMemSize -= p->mh_size;
debugMemBlocks--;
#ifdef MEM_LIST
debugmem_list_delete(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr,
"xmlReallocLoc : Unsigned overflow\n");
return(NULL);
}
tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
if (!tmp) {
free(p);
goto error;
}
p = tmp;
if (xmlMemTraceBlockAt == ptr) {
fprintf(stderr,
"%p : Realloced(%lu -> %lu) Ok\n",
xmlMemTraceBlockAt, (long unsigned)p->mh_size,
(long unsigned)size);
xmlMallocBreakpoint();
}
p->mh_tag = MEMTAG;
p->mh_number = number;
p->mh_type = REALLOC_TYPE;
p->mh_size = size;
p->mh_file = file;
p->mh_line = line;
xmlMutexLock(&xmlMemMutex);
debugMemSize += size;
debugMemBlocks++;
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
debugmem_list_add(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
TEST_POINT
return(HDR_2_CLIENT(p));
error:
return(NULL);
return(xmlMemRealloc(ptr, size));
}
/**
@ -365,10 +151,45 @@ error:
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
xmlMemRealloc(void *ptr,size_t size) {
return(xmlReallocLoc(ptr, size, "none", 0));
xmlMemRealloc(void *ptr, size_t size) {
MEMHDR *p, *tmp;
size_t oldSize;
if (ptr == NULL)
return(xmlMemMalloc(size));
xmlInitParser();
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr, "xmlMemRealloc: Unsigned overflow\n");
return(NULL);
}
p = CLIENT_2_HDR(ptr);
if (p->mh_tag != MEMTAG) {
fprintf(stderr, "xmlMemRealloc: Tag error\n");
return(NULL);
}
oldSize = p->mh_size;
p->mh_tag = ~MEMTAG;
tmp = (MEMHDR *) realloc(p, RESERVE_SIZE + size);
if (!tmp) {
p->mh_tag = MEMTAG;
fprintf(stderr, "xmlMemRealloc: Out of memory\n");
return(NULL);
}
p = tmp;
p->mh_tag = MEMTAG;
p->mh_size = size;
xmlMutexLock(&xmlMemMutex);
debugMemSize -= oldSize;
debugMemSize += size;
xmlMutexUnlock(&xmlMemMutex);
return(HDR_2_CLIENT(p));
}
/**
@ -381,53 +202,30 @@ void
xmlMemFree(void *ptr)
{
MEMHDR *p;
char *target;
if (ptr == NULL)
return;
return;
if (ptr == (void *) -1) {
fprintf(stderr,
"trying to free pointer from freed area\n");
goto error;
fprintf(stderr, "xmlMemFree: Pointer from freed area\n");
return;
}
if (xmlMemTraceBlockAt == ptr) {
fprintf(stderr,
"%p : Freed()\n", xmlMemTraceBlockAt);
xmlMallocBreakpoint();
}
TEST_POINT
target = (char *) ptr;
p = CLIENT_2_HDR(ptr);
if (p->mh_tag != MEMTAG) {
Mem_Tag_Err(p);
goto error;
fprintf(stderr, "xmlMemFree: Tag error\n");
return;
}
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
p->mh_tag = ~MEMTAG;
memset(target, -1, p->mh_size);
memset(ptr, -1, p->mh_size);
xmlMutexLock(&xmlMemMutex);
debugMemSize -= p->mh_size;
debugMemBlocks--;
#ifdef MEM_LIST
debugmem_list_delete(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
free(p);
TEST_POINT
return;
error:
fprintf(stderr,
"xmlMemFree(%p) error\n", ptr);
xmlMallocBreakpoint();
return;
}
@ -437,64 +235,15 @@ error:
* @file: the file name or NULL
* @line: the line number
*
* a strdup() equivalent, with logging of the allocation info.
* DEPRECATED: don't use
*
* Returns a pointer to the new string or NULL if allocation error occurred.
*/
char *
xmlMemStrdupLoc(const char *str, const char *file, int line)
xmlMemStrdupLoc(const char *str, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED)
{
char *s;
size_t size = strlen(str) + 1;
MEMHDR *p;
xmlInitParser();
TEST_POINT
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr,
"xmlMemStrdupLoc : Unsigned overflow\n");
return(NULL);
}
p = (MEMHDR *) malloc(RESERVE_SIZE+size);
if (!p) {
goto error;
}
p->mh_tag = MEMTAG;
p->mh_size = size;
p->mh_type = STRDUP_TYPE;
p->mh_file = file;
p->mh_line = line;
xmlMutexLock(&xmlMemMutex);
p->mh_number = ++block;
debugMemSize += size;
debugMemBlocks++;
if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
debugmem_list_add(p);
#endif
xmlMutexUnlock(&xmlMemMutex);
s = (char *) HDR_2_CLIENT(p);
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
strcpy(s,str);
TEST_POINT
if (xmlMemTraceBlockAt == s) {
fprintf(stderr,
"%p : Strdup() Ok\n", xmlMemTraceBlockAt);
xmlMallocBreakpoint();
}
return(s);
error:
return(NULL);
return(xmlMemoryStrdup(str));
}
/**
@ -505,10 +254,37 @@ error:
*
* Returns a pointer to the new string or NULL if allocation error occurred.
*/
char *
xmlMemoryStrdup(const char *str) {
return(xmlMemStrdupLoc(str, "none", 0));
char *s;
size_t size = strlen(str) + 1;
MEMHDR *p;
xmlInitParser();
if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
fprintf(stderr, "xmlMemoryStrdup: Unsigned overflow\n");
return(NULL);
}
p = (MEMHDR *) malloc(RESERVE_SIZE + size);
if (!p) {
fprintf(stderr, "xmlMemoryStrdup: Out of memory\n");
return(NULL);
}
p->mh_tag = MEMTAG;
p->mh_size = size;
xmlMutexLock(&xmlMemMutex);
debugMemSize += size;
debugMemBlocks++;
xmlMutexUnlock(&xmlMemMutex);
s = (char *) HDR_2_CLIENT(p);
memcpy(s, str, size);
return(s);
}
/**
@ -565,256 +341,47 @@ xmlMemBlocks(void) {
/**
* xmlMemDisplayLast:
* @fp: a FILE descriptor used as the output file, if NULL, the result is
* written to the file .memorylist
* @fp: a FILE descriptor
* @nbBytes: the amount of memory to dump
*
* the last nbBytes of memory allocated and not freed, useful for dumping
* the memory left allocated between two places at runtime.
* DEPRECATED: This feature was removed.
*/
void
xmlMemDisplayLast(FILE *fp, long nbBytes)
xmlMemDisplayLast(FILE *fp ATTRIBUTE_UNUSED, long nbBytes ATTRIBUTE_UNUSED)
{
#ifdef MEM_LIST
MEMHDR *p;
unsigned idx;
int nb = 0;
#endif
FILE *old_fp = fp;
if (nbBytes <= 0)
return;
if (fp == NULL) {
fp = fopen(".memorylist", "w");
if (fp == NULL)
return;
}
#ifdef MEM_LIST
fprintf(fp," Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n",
nbBytes, debugMemSize, debugMaxMemSize);
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
idx = 0;
xmlMutexLock(&xmlMemMutex);
p = memlist;
while ((p) && (nbBytes > 0)) {
fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
(unsigned long)p->mh_size);
switch (p->mh_type) {
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
default:
fprintf(fp,"Unknown memory block, may be corrupted");
xmlMutexUnlock(&xmlMemMutex);
if (old_fp == NULL)
fclose(fp);
return;
}
if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
if (p->mh_tag != MEMTAG)
fprintf(fp," INVALID");
nb++;
fprintf(fp,"\n");
nbBytes -= (unsigned long)p->mh_size;
p = p->mh_next;
}
xmlMutexUnlock(&xmlMemMutex);
#else
fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
#endif
if (old_fp == NULL)
fclose(fp);
}
/**
* xmlMemDisplay:
* @fp: a FILE descriptor used as the output file, if NULL, the result is
* written to the file .memorylist
* @fp: a FILE descriptor
*
* show in-extenso the memory blocks allocated
* DEPRECATED: This feature was removed.
*/
void
xmlMemDisplay(FILE *fp)
xmlMemDisplay(FILE *fp ATTRIBUTE_UNUSED)
{
#ifdef MEM_LIST
MEMHDR *p;
unsigned idx;
int nb = 0;
time_t currentTime;
char buf[500];
struct tm * tstruct;
#endif
FILE *old_fp = fp;
if (fp == NULL) {
fp = fopen(".memorylist", "w");
if (fp == NULL)
return;
}
#ifdef MEM_LIST
currentTime = time(NULL);
tstruct = localtime(&currentTime);
strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct);
fprintf(fp," %s\n\n", buf);
fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
debugMemSize, debugMaxMemSize);
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
idx = 0;
xmlMutexLock(&xmlMemMutex);
p = memlist;
while (p) {
fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
(unsigned long)p->mh_size);
switch (p->mh_type) {
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
default:
fprintf(fp,"Unknown memory block, may be corrupted");
xmlMutexUnlock(&xmlMemMutex);
if (old_fp == NULL)
fclose(fp);
return;
}
if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
if (p->mh_tag != MEMTAG)
fprintf(fp," INVALID");
nb++;
fprintf(fp,"\n");
p = p->mh_next;
}
xmlMutexUnlock(&xmlMemMutex);
#else
fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
#endif
if (old_fp == NULL)
fclose(fp);
}
#ifdef MEM_LIST
static void debugmem_list_add(MEMHDR *p)
{
p->mh_next = memlist;
p->mh_prev = NULL;
if (memlist) memlist->mh_prev = p;
memlist = p;
}
static void debugmem_list_delete(MEMHDR *p)
{
if (p->mh_next)
p->mh_next->mh_prev = p->mh_prev;
if (p->mh_prev)
p->mh_prev->mh_next = p->mh_next;
else memlist = p->mh_next;
}
#endif
/*
* debugmem_tag_error:
*
* internal error function.
*/
static void debugmem_tag_error(void *p)
{
fprintf(stderr,
"Memory tag error occurs :%p \n\t bye\n", p);
#ifdef MEM_LIST
if (stderr)
xmlMemDisplay(stderr);
#endif
}
#ifdef MEM_LIST
static FILE *xmlMemoryDumpFile = NULL;
#endif
/**
* xmlMemShow:
* @fp: a FILE descriptor used as the output file
* @fp: a FILE descriptor
* @nr: number of entries to dump
*
* show a show display of the memory allocated, and dump
* the @nr last allocated areas which were not freed
* DEPRECATED: This feature was removed.
*/
void
xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED)
xmlMemShow(FILE *fp ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED)
{
#ifdef MEM_LIST
MEMHDR *p;
#endif
if (fp != NULL)
fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
debugMemSize, debugMaxMemSize);
#ifdef MEM_LIST
xmlMutexLock(&xmlMemMutex);
if (nr > 0) {
fprintf(fp,"NUMBER SIZE TYPE WHERE\n");
p = memlist;
while ((p) && nr > 0) {
fprintf(fp,"%6lu %6lu ",p->mh_number,(unsigned long)p->mh_size);
switch (p->mh_type) {
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
default:fprintf(fp," ??? in ");break;
}
if (p->mh_file != NULL)
fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
if (p->mh_tag != MEMTAG)
fprintf(fp," INVALID");
fprintf(fp,"\n");
nr--;
p = p->mh_next;
}
}
xmlMutexUnlock(&xmlMemMutex);
#endif /* MEM_LIST */
}
/**
* xmlMemoryDump:
*
* Dump in-extenso the memory blocks allocated to the file .memorylist
* DEPRECATED: This feature was removed.
*/
void
xmlMemoryDump(void)
{
#ifdef MEM_LIST
FILE *dump;
if (debugMaxMemSize == 0)
return;
dump = fopen(".memdump", "w");
if (dump == NULL)
xmlMemoryDumpFile = stderr;
else xmlMemoryDumpFile = dump;
xmlMemDisplay(xmlMemoryDumpFile);
if (dump != NULL) fclose(dump);
#endif /* MEM_LIST */
}
@ -844,18 +411,7 @@ xmlInitMemory(void) {
*/
void
xmlInitMemoryInternal(void) {
char *breakpoint;
xmlInitMutex(&xmlMemMutex);
breakpoint = getenv("XML_MEM_BREAKPOINT");
if (breakpoint != NULL) {
sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
}
breakpoint = getenv("XML_MEM_TRACE");
if (breakpoint != NULL) {
sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
}
xmlInitMutex(&xmlMemMutex);
}
/**