On 10-10-30 10:22 PM, Sohail Somani wrote:

After fixing this, another leak remains. I've attached both the patch
and the modified test code with the valgrind trace.

Well I think I know where the leak is coming from. Here we use the save implementation from the session:

    session()->implSave(*this); // ptr_impl.h:45

At this point, the this (MetaDbo<C>) object has a reference count of 1 because it is held in the dirtyObjects_ variable.

In the implSave function:

  // Session_impl.h:180
  transaction_->objects_.push_back(new ptr<C>(&dbo));

In this call, the ptr<C> constructor increments the reference count. So now the reference count is 2.

Then if exceptions happen when committing the transaction, the reference count is never decremented. Instant memory leak.

I would recommend going through all the places where a decRef is required at the end of scope and replacing the imperative statements with a scope guard.

Anyway, I've attached a patch and tests that fix all the leaks in my model tests, according to valgrind.

I guess I have to stop telling people that memory leaks in C++ are a thing of the past!

Keep up the good work, love dbo.

--
Sohail Somani
--
iBlog : http://uint32t.blogspot.com
iTweet: http://twitter.com/somanisoftware
iCode : http://bitbucket.org/cheez

diff -r 042b12c62486 -r a49c42291b87 vendor/Wt/Wt/Dbo/Session.C
--- a/vendor/Wt/Wt/Dbo/Session.C        Sat Oct 30 15:53:13 2010 -0700
+++ b/vendor/Wt/Wt/Dbo/Session.C        Sat Oct 30 22:52:02 2010 -0700
@@ -152,7 +152,15 @@
     MetaDboBaseSet::iterator i = dirtyObjects_.begin();
     MetaDboBase *dbo = *i;
     dirtyObjects_.erase(i);
-    dbo->flush();
+    try
+    {
+      dbo->flush();
+    }
+    catch(...)
+    {
+      dbo->decRef();
+      throw;
+    }
     dbo->decRef();
   }
 }
diff -r 042b12c62486 -r a49c42291b87 vendor/Wt/Wt/Dbo/Session_impl.h
--- a/vendor/Wt/Wt/Dbo/Session_impl.h   Sat Oct 30 15:53:13 2010 -0700
+++ b/vendor/Wt/Wt/Dbo/Session_impl.h   Sat Oct 30 22:52:02 2010 -0700
@@ -22,6 +22,10 @@
   ClassMapping<C> *mapping = new ClassMapping<C>();
   mapping->tableName = tableName;
 
+  ClassRegistry::iterator i = classRegistry_.find(&typeid(C));
+  if(i != classRegistry_.end())
+    delete i->second;
+
   classRegistry_[&typeid(C)] = mapping;
   tableRegistry_[tableName] = mapping;
 }
diff -r 042b12c62486 -r a49c42291b87 vendor/Wt/Wt/Dbo/Transaction.C
--- a/vendor/Wt/Wt/Dbo/Transaction.C    Sat Oct 30 15:53:13 2010 -0700
+++ b/vendor/Wt/Wt/Dbo/Transaction.C    Sat Oct 30 22:52:02 2010 -0700
@@ -45,13 +45,13 @@
 bool Transaction::commit()
 {
   if (isActive()) {
-    committed_ = true;
 
     if (impl_->transactionCount_ == 1) {
       impl_->commit();
-
+      committed_ = true;
       return true;
     } else
+      committed_ = true;
       return false;
   } else
     return false;
struct Class
{
  Class():integer(5){}

  int integer;

  template<typename Action>
  void
  persist(Action & a)
  {
    dbo::field(a,integer,"integer");
  }
};

KIMI_UNIT_TEST( TestWtMapClassMemoryLeak )
{
  dbo::backend::Sqlite3 connection(":memory:");
  dbo::Session session;
  session.setConnection(connection);

  session.mapClass<Class>("class");
  session.mapClass<Class>("class"); // This used to leak because the old 
mapping was overwritten
}

KIMI_UNIT_TEST( TestWtFlushLeak )
{
  dbo::backend::Sqlite3 connection(":memory:");
  dbo::Session session;
  session.setConnection(connection);

  session.mapClass<Class>("class");

  Wt::Dbo::Transaction t(session);

  session.add(new Class);

  BOOST_REQUIRE_THROW(t.commit(),std::runtime_error); // This used to leak 
because an exception was thrown
}
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in  U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store 
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
witty-interest mailing list
witty-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to