GNOME Bugzilla – Bug 132014
Memory leak in throwing exception
Last modified: 2004-12-22 21:47:04 UTC
My apology if this bug is fixed in libxml++-2.5 + It seems that there is memory leak in exception throwing mechanism. int main() { xmlpp::SaxParser sp; std::string xmlString = "<ACK></NACK>"; while(1) try { sp.parse_memory(xmlString); } catch(std::exception& e) { } } and verifying memory usage with 'ps' command shows that the process memory is increasing. throw *this; in xmlpp::exception::Raise() does not delete the memory.
Hi, Could you try this quick patch on libxml++/parser/saxparser.cc. I think it should fix the memory leak. Thanks for your feedback. Christophe cvs diff: Diffing . Index: saxparser.cc =================================================================== RCS file: /cvs/gnome/libxml++/libxml++/parsers/saxparser.cc,v retrieving revision 1.1.1.1 diff -r1.1.1.1 saxparser.cc 157a158,159 > { > release_underlying(); 158a161 > }
My mistake... This patch corrects nothing. I'll investigate it later.
Problem: class Parser { ..... exception* exception_; ..... }; saxparser.cc: if (exception condition) exception_ = new object_of_type_exception(); check_for_exception(); parser.cc: check_for_exception() { check_for_validity_messages(); if (exception_) { exception* tmp = exception_; exception_ = 0; tmp->Raise(); // Memory leak; } } exception.cc: void exception::Raise() const { throw *this; // creates a new temporary object and throws it. // Hence, destructor of new temporary object gets // called and not of 'this' (and in turn 'tmp') // points to. } Fix (?): exception.cc: void exception::Raise() { std::auto_ptr<exception> tmp = this; throw *this; }
I'm not sure what memory you think is leaking. What does valgrind say?
exception.cc: void exception::Raise() const { throw *this; // This statement does not call delete // for object created by // // if (exception condition) // exception_ = new object_of_type_exception(); // in saxparser.cc // // an explicit delete is necessary to delete // unless the pointer is wrapped in auto_ptr }
The following patch fixes, on my computer, the problem outlined by the initial example. I'll commit this ASAP. Cheers Christophe =================================================================== RCS file: /cvs/gnome/libxml++/libxml++/parsers/parser.cc,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 parser.cc --- parser.cc 18 Dec 2003 16:36:14 -0000 1.1.1.1 +++ parser.cc 29 Jan 2004 15:25:26 -0000 @@ -189,7 +189,7 @@ if(exception_) { - exception* tmp = exception_; + std::auto_ptr<exception> tmp ( exception_ ); exception_ = 0; tmp->Raise(); }
Hi, I have a similar problem with a broken XML file. My libxml++ is rather old, but it already has the last fix from Christophe. Attached is a small testcase to reproduce the problem. Please let me know if it still exists in the lastest libxml++ version. libxml2 version: 2.6.10 libmxl++ version: 0.27.0 Cheers, Thomas broken.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE data SYSTEM "data.dtd"> <data> <user>admin & test</user> </data> testcase.cpp: #include <libxml++/libxml++.h> int main(void) { while (1) { try { xmlpp::DomParser parser; parser.set_validate(false); parser.parse_file("broken.xml"); } catch(...) { } } return 0; }
Ok, just checked libxml++-2.6.1, the bug is there too.
This last issue is not related to the initial one. I created another bugreport: http://bugzilla.gnome.org/show_bug.cgi?id=150082