Re: gdb help: debugging a segfault in boost::shared_ptr



I can't believe I missed that.

I store the connections in a list std::list<PoolObject>, where
PoolObject is a wrapper that contains the pointer and some other data.

When checking out a connection, I get a reference to each PoolObject in
order to conveniently check for expiration and such. If this connection
is ok to be checked out, I move it to a "used" list, and use the same
reference as before to return the pointer. This obviously doesn't work
very well :)

A stupid mistake, but atleast I've lea rned alot while trying to figure
this out.

Thank you all for helping me out. You've been great. And a special
thanks to Paul for continously stating "the obvious" :) You've
certainly got a great eye for detail.


On Dec 6, 11:23 pm, Paul Pluzhnikov <ppluzhnikov-...@xxxxxxxxxxx>
wrote:
"phear" <phear.d...@xxxxxxxxx> writes:
Valgrind also reports two errors that is likely related:I think this is *the* cause of your crashes, and I believe you are
not interpreting these errors correctly.



==9500== Invalid read of size 4
==9500== at 0x43FD729: boost::detail::shared_count::shared_count(boost::detail::shared_count const&) (shared_count.hpp:165)
==9500== by 0x43FD9DB: boost::shared_ptr<IDatabaseAdapter>::shared_ptr(boost::shared_ptr<IDatabaseAdapter> const&) (shared_ptr.hpp:106)
==9500== by 0x43FD28F: DatabaseAdapterPool::GetAdapter(DataSource const&) (DatabaseAdapterPool.cc:188)
==9500== by 0x43E30A2: IDatabaseAdapter::GetAdapter(DataSource const&) (DatabaseAdapter.cc:31)
==9500== by 0x43F6A99: Instance::GetListEntryWithFields(...) > (Instance.cc:505)
==9500== by 0x43E6F25: ARDBCGetListEntryWithFields (syscomardbc.cc:757)
==9500== by 0x804D011: ardbctest::testGetListEntryWithFields() (ardbctest.h:458)
==9500== by 0x804E11D: ardbctest::run() (ardbctest.h:180)
==9500== by 0x8049CAA: run() (main.cc:47)
==9500== by 0x8049EBB: main (main.cc:68)
==9500== Address 0x591D60C is 20 bytes inside a block of size 24 free'd
==9500== at 0x401D268: operator delete(void*) (vg_replace_malloc.c:246)
==9500== by 0x43FDF68: __gnu_cxx::new_allocator<...>::deallocate(...) (new_allocator.h:94)
==9500== by 0x43FDF9D: std::_List_base<... >::_M_put_node(...) (stl_list.h:317)
==9500== by 0x43FE1CA: std::list<...>::_M_erase(...) (stl_list.h:1163)
==9500== by 0x43FE22C: std::list<...>::erase(...) (list.tcc:98)
==9500== by 0x43FCD07: DatabaseAdapterPool::InternalPool::GetAdapter() (DatabaseAdapterPool.cc:68)Let me translate that message for you:

in DatabaseAdapterPool.cc:188 you are accessing shared_ptr which
resides in a list node, and that list node has already been free()d
by list::erase() operation, called from DatabaseAdapterPool.cc:68

These only confirm what I already know though.No, they tell you exact problem which you didn't know: that you
are mis-using std::list().

In particular, your bug is likely along the lines of:

list<...>::iterator it = someList.begin(); // [1]
someList.erase(it); // invalidates it and *it !!! // [2]
...
return it->someField; // read dangling! // [3]

The reason you observe crash/corruption only with multiple threads,
is that between points [2] and [3] the memory that you'll be using at
3 is free -- so some other threads can malloc() it, and write its
own data over it; corrupting it before you get to point [3].

Without interference from another thread, the memory will not change,
so at [3] the value of someField will be the same it was before [2]
(unless code between [2] and [3] also does malloc()s).

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

.



Relevant Pages

  • Re: Passing in SqlConnection by ref
    ... My concern was if I pass in connection to another method, ... it in with "ref" to accomplish that. ... less do the same thing (it's a true pointer as oppose to reference type). ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Passing in SqlConnection by ref
    ... My concern was if I pass in connection to another method, ... it in with "ref" to accomplish that. ... less do the same thing (it's a true pointer as oppose to reference type). ...
    (microsoft.public.dotnet.framework.adonet)
  • Re: Passing in SqlConnection by ref
    ... On one hand SqlConnection is an object and passed by ... reference (which is a "memory address" or "pointer") by default but on ... >> Object A opens a Sql Db connection to execute number of SqlCommands. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Passing in SqlConnection by ref
    ... On one hand SqlConnection is an object and passed by ... reference (which is a "memory address" or "pointer") by default but on ... >> Object A opens a Sql Db connection to execute number of SqlCommands. ...
    (microsoft.public.dotnet.framework.adonet)
  • Re: Question on LSP
    ... Sure, the developer must keep track of which type has been assigned to each pointer to manage complexity in creating the design, which is why the 'T' is in T*. ... Subtyping is a relation which does not ... Those object types are completely orthogonal to the semantics of being an object reference. ... aggregate references, is the aggregate of referenced objects or target ...
    (comp.object)

Loading