Hi,
I've been debugging a problem with my memory manager for quite a while (I
was playing with different block sizes) when I discovered there doesn't
seem to be a bug but the heap gets corrupted by some other place in PHP. It
just happens that the memory manager makes this problem appear sooner.
The problem seems to be in xmlCleanupParser() of the simplexml extension.
Not sure if this is a bug in simplexml or libXML2.
On an empty script I get the following reports from valgrind. Can someone
with a more intimate knowledge of this module or libXML2 please take a
look? (bug.php is an empty script)
Thanks, Andi
[andi@ ~/php5]$ valgrind sapi/cli/php bug.php
==2074== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==2074== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==2074== Using valgrind-20030725, a program supervision framework for
x86-linux.
==2074== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==2074== Estimated CPU clock rate is 551 MHz
==2074== For more details, rerun with: -v
==2074==
==2074== Invalid read of size 4
==2074== at 0x403A8D4C: __pthread_mutex_destroy (vg_libpthread.c:1010)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC32C is 4 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D69: __pthread_mutex_destroy (vg_libpthread.c:1019)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC32C is 4 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D70: __pthread_mutex_destroy (vg_libpthread.c:1020)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC330 is 8 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D77: __pthread_mutex_destroy (vg_libpthread.c:1021)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC334 is 12 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid free() / delete / delete[]
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC328 is 0 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 4 from 2)
==2074== malloc/free: in use at exit: 288 bytes in 3 blocks.
==2074== malloc/free: 3457 allocs, 3455 frees, 513425 bytes allocated.
==2074== For a detailed leak analysis, rerun with: --leak-check=yes
==2074== For counts of detected errors, rerun with: -v
Hi,
I've been debugging a problem with my memory manager for quite a while (I
was playing with different block sizes) when I discovered there doesn't
seem to be a bug but the heap gets corrupted by some other place in PHP. It
just happens that the memory manager makes this problem appear sooner.
The problem seems to be in xmlCleanupParser() of the simplexml extension.
Not sure if this is a bug in simplexml or libXML2.
On an empty script I get the following reports from valgrind. Can someone
with a more intimate knowledge of this module or libXML2 please take a
look? (bug.php is an empty script)
you are likely to have a buggy version of libXml, that
causes this when xmlCleanupParser is called more than once.
this happens if two php-modules use libXml and call
xmlCleanupParser in the [R|M]SHUTDOWN
re,
tc
Thanks, Andi
[andi@ ~/php5]$ valgrind sapi/cli/php bug.php
==2074== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==2074== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==2074== Using valgrind-20030725, a program supervision framework for
x86-linux.
==2074== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==2074== Estimated CPU clock rate is 551 MHz
==2074== For more details, rerun with: -v
==2074==
==2074== Invalid read of size 4
==2074== at 0x403A8D4C: __pthread_mutex_destroy (vg_libpthread.c:1010)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC32C is 4 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D69: __pthread_mutex_destroy (vg_libpthread.c:1019)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC32C is 4 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D70: __pthread_mutex_destroy (vg_libpthread.c:1020)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC330 is 8 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid write of size 4
==2074== at 0x403A8D77: __pthread_mutex_destroy (vg_libpthread.c:1021)
==2074== by 0x40344CFC: xmlFreeMutex (threads.c:138)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC334 is 12 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== Invalid free() / delete / delete[]
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074== Address 0x418FC328 is 0 bytes inside a block of size 24 free'd
==2074== at 0x40025722: free (vg_replace_malloc.c:220)
==2074== by 0x40344D04: xmlFreeMutex (threads.c:142)
==2074== by 0x40344189: xmlCleanupGlobals (globals.c:49)
==2074== by 0x402F7C39: xmlCleanupParser (parser.c:11179)
==2074==
==2074== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 4 from 2)
==2074== malloc/free: in use at exit: 288 bytes in 3 blocks.
==2074== malloc/free: 3457 allocs, 3455 frees, 513425 bytes allocated.
==2074== For a detailed leak analysis, rerun with: --leak-check=yes
==2074== For counts of detected errors, rerun with: -v--
--
Thies C. Arntzen - Looking for all sorts of freelance work - just ask..
http://www.amazon.de/exec/obidos/wishlist/AB9DY62QWDSZ
At 03:09 PM 8/30/2003 +0200, Thies C. Arntzen wrote:
you are likely to have a buggy version of libXml, that causes this when xmlCleanupParser is called more than once. this happens if two php-modules use libXml and call xmlCleanupParser in the [R|M]SHUTDOWN
Ouch. Now the question is how do we solve this? Do we make ./configure bail
out on such versions or do we hack something into PHP so that it doesn't
call this function more than once?
I really want to reduce the block size in my mem manager from 256KB to 16KB
but I can't do it right now because it kills PHP quicker (it will die in
any case but it will take longer).
Thanks,
Andi
From: Andi Gutmans
Ouch. Now the question is how do we solve this? Do we make ./configure
bail
out on such versions or do we hack something into PHP so that it doesn't
call this function more than once?
I really want to reduce the block size in my mem manager from 256KB to
16KB
but I can't do it right now because it kills PHP quicker (it will die in
any case but it will take longer).
Do you know what happens if another apache mod were to be using libxml
(there are some)? Would they be sharing the same space as in, if the other
mod were to change libxml globals, would that affect the libxml globals
within the php scope? I believe they would clash but dont know for sure.
If so, then libxml 2.5.8 would have to be marked bad unless you can also
know when the other mods call their cleanup. This is a 2.5.8 issue only as
it was introduce in that version and fixed in 2.5.9.
Rob
At 09:56 AM 8/30/2003 -0400, Rob Richards wrote:
From: Andi Gutmans
Ouch. Now the question is how do we solve this? Do we make ./configure
bail
out on such versions or do we hack something into PHP so that it doesn't
call this function more than once?
I really want to reduce the block size in my mem manager from 256KB to
16KB
but I can't do it right now because it kills PHP quicker (it will die in
any case but it will take longer).Do you know what happens if another apache mod were to be using libxml
(there are some)? Would they be sharing the same space as in, if the other
mod were to change libxml globals, would that affect the libxml globals
within the php scope? I believe they would clash but dont know for sure.
They probably would.
If so, then libxml 2.5.8 would have to be marked bad unless you can also
know when the other mods call their cleanup. This is a 2.5.8 issue only as
it was introduce in that version and fixed in 2.5.9.
Can someone who knows configure well please add a check and bail out on 2.5.8?
Thanks,
Andi
If so, then libxml 2.5.8 would have to be marked bad unless you can also
know when the other mods call their cleanup. This is a 2.5.8 issue only as
it was introduce in that version and fixed in 2.5.9.Can someone who knows configure well please add a check and bail out on 2.5.8?
I can add that..but shouldn't we just go ahead and require
2.5.9 or greater instead of skipping ONE version??
--Jani
The current support for references is mediocre at best. For instance:
class foobar
{
var $variable;
function foobar()
{
$variable = "foobar";
}
}
//This form of new assignment should be the default
$a = & new foobar();
$b = & new foobar();
$b->variable = "Hello";
$array = array(&$a, &$b);
//The foreach construct uses copies instead of references.
foreach ($array as $element)
$element->variable = "Hi";
echo $a->variable; //echoes "foobar"
echo $b->variable; //echoes "Hello";
//In order for the above to work, a loop is required.
for ($i = 0, $count = count($array); $i < $count; $i++)
{
$element = &$array[$i]; //shown explicitly.
$element->variable = "Hi";
}
echo $a->variable; //echoes "Hi"
echo $b->variable; //echoes "Hi";
//Variable args are always copies,
Function foo()
{
$args = func_get_args()
//even loop doesn't work:
for ($i = 0, $count = count($args); $i < $count; $i++)
{
$element = &$args[$i];
$element->variable = "Hello";
}
}
foo(&$a, &$b);
echo $a->variable; //echoes "Hi"
echo $b->variable; //echoes "Hi";
Thanks for your time,
LingWitt@insightbb.com