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:
parent
5e80f4381b
commit
1cdfece12b
@ -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()
|
||||
|
@ -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)
|
||||
|
16
configure.ac
16
configure.ac
@ -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
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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>
|
||||
|
16
globals.c
16
globals.c
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
4
parser.c
4
parser.c
@ -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);
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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");
|
||||
|
698
xmlmemory.c
698
xmlmemory.c
@ -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(¤tTime);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user