Boost logo

Boost Users :

From: Stephen Torri (storri_at_[hidden])
Date: 2007-03-29 13:31:26


I have a class, called Reader_Factory, which creates file readers for a
particular input file based on its type. Other objects will request a
certain type of reader multiple times so I am caching the reader object
in a STL map with its file name as the key.

        std::map<std::string, boost::shared_ptr<Reader> >

Well when I include in sp_debug_hooks.cpp into my build along with
defining -DBOOST_SP_ENABLE_DEBUG_HOOKS in the compiler's command line
flags I am seeing a error come up with its destroying the
Reader_Factory.

        *** errors detected in test suite "Reverse_Impl test suite"; see standard output for details
        test_one_node_per_section: sp_debug_hooks.cpp:201: void operator delete(void*): Assertion `*pm == allocated_scalar' failed.

Checking the back trace in gdb (full backtrace below) I am seeing that
Reader_Factory destructor is called followed by the std::map destructor
followed by the reader object's destructor. So this made me think that
perhaps I am doing something wrong with storing a reader object in the
Reader_Factory class. Well gdb reports back that there was a
segmentation fault in a destructor for a class called Data_Source. The
line reades:

26 m_transfer_method->close();

Checking m_transfer_method in gdb reports:

(gdb) p m_transfer_method
$3 = {px = 0x8d8af58, pn = {pi_ = 0x8d8af80, id_ = 741732609}}
(gdb) p *m_transfer_method.px
$4 = {<libreverse::infrastructure::Data_Transfer_Base> = {_vptr.Data_Transfer_Base = 0x4}, m_config = {px = 0x8d7ff28,
    pn = {pi_ = 0x8d7ff40, id_ = 741732609}}, m_data = {px = 0x8d87360, pn = {pi_ = 0x8d873c8, id_ = 741732609}}}

So I am not sure what is the segfault here. To help here is pseudo code
similiar to what I am doing:

class File_Reader {
};

class B_Reader : public File_Reader
{};

class Reader_Factory {
public:

        virtual ~Reader_Factory(){}

        boost::shared_ptr<File_Reader> create_B_Reader ( std::string filename )
        {
                boost::shared_ptr<File_Reader> tmp_ptr ( new B_Reader ( filename ) );
                IF tmp_ptr->support_File_Type is TRUE THEN
                   return reader
                ELSE
                   throw an exception
        }

        boost::shared_ptr<File_Reader> get_Reader ( std::string filename )
        {
                bool found = false;
                boost::shared_ptr<File_Reader> reader_ptr;

                // IF the File_Reader is already cached in the map THEN return pointer to it
                // ELSE
                // Find which reader will support it THEN set found to TRUE
                // (For example, see create_B_Reader)
                // IF found equal to TRUE and reader_ptr is set THEN check to see if its in the reader map
                // IF not THEN add it
                // ELSE we should not reach this point (abort. If it exists already then the first IF statement will catch it)

                Reader_Map_t::const_iterator cpos = reader_map.find ( filename );
                if ( cpos == reader_map.end() )
                {
                        try {
                                reader_ptr = this->create_B_Reader ( filename );
                                found = true;
                        }
                        catch ( std::exception& )
                        {
                                found = false;
                        }

                        if ( ! found ) THEN throw exception saying unsupported file type
                        else
                        {
                                if ( ( reader_map.insert ( std::make_pair ( filename, reader_ptr ) ) ).second == false )
                                THEN report exception saying duplicate entry the program is broken stop running
                        }
                }
                else
                {
                        reader_ptr = (*cpos).second;
                }

                return reader_ptr;
        }

        typedef std::map<std::string, boost::shared_ptr<File_Reader> > Reader_Map_t;
        Reader_Map_t reader_map;
};

Is there a problem or problems with this design?

Stephen

----------------------------------------------------------------------------
Full gdb output from SIGABRT given by sp_debug_hooks
----------------------------------------------------------------------------
#0 0x00367402 in __kernel_vsyscall ()
#1 0x47bd9d40 in raise () from /lib/libc.so.6
#2 0x47bdb591 in abort () from /lib/libc.so.6
#3 0x47bd338b in __assert_fail () from /lib/libc.so.6
#4 0x006c20ae in operator delete (p=0x8d9f2a8) at sp_debug_hooks.cpp:201
#5 0x006d4983 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int const, unsigned int> > >::deallocate (
    this=0x8d8ae4c, __p=0x8d9f2a8)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/ext/new_allocator.h:94
#6 0x006d49b8 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_put_node (this=0x8d8ae4c, __p=0x8d9f2a8)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:362
#7 0x006d4a18 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::destroy_node (this=0x8d8ae4c, __p=0x8d9f2a8)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:392
#8 0x006d4a8e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_erase (this=0x8d8ae4c, __x=0x8d9f2a8) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1266
#9 0x006d4a6e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_erase (this=0x8d8ae4c, __x=0x8d9e1a0) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1264
#10 0x006d4a6e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_erase (this=0x8d8ae4c, __x=0x8d9df20) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1264
#11 0x006d4a6e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_erase (this=0x8d8ae4c, __x=0x8d9d520) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1264
#12 0x006d4a6e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_erase (this=0x8d8ae4c, __x=0x8d9c120) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1264
#13 0x006d4acd in ~_Rb_tree (this=0x8d8ae4c)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:578
#14 0x006d4b29 in ~map (this=0x8d8ae4c)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_map.h:93
#15 0x006d0407 in ~Memory_Map (this=0x8d8ae28) at Memory_Map.cpp:75
#16 0x006d3ba8 in boost::checked_delete<libreverse::data_types::Memory_Map> (x=0x8d8ae28)
    at /usr/include/boost/checked_delete.hpp:34
#17 0x006d6645 in boost::detail::sp_counted_impl_p<libreverse::data_types::Memory_Map>::dispose (this=0x8d9e318)
#18 0x0805e62c in boost::detail::sp_counted_base::release (this=0x8d9e318)
    at /usr/include/boost/detail/sp_counted_base_gcc_x86.hpp:145
#19 0x0805e66e in ~shared_count (this=0x8d89c38) at /usr/include/boost/detail/shared_count.hpp:159
#20 0x006d3024 in ~shared_ptr (this=0x8d89c34) at /usr/include/boost/shared_ptr.hpp:106
#21 0x00703c65 in ~File (this=0x8d89c28) at File.cpp:83
#22 0x0077c9bd in ~Elf_File (this=0x8d89c28) at ../../../../src/io/input/File_Readers/Elf/Elf_Header_Eident.h:10
#23 0x0077c9ed in boost::checked_delete<libreverse::elf_module::Elf_File<32u> > (x=0x8d89c28)
    at /usr/include/boost/checked_delete.hpp:34
#24 0x0077cb59 in boost::detail::sp_counted_impl_p<libreverse::elf_module::Elf_File<32u> >::dispose (this=0x8d9e788)
    at /usr/include/boost/detail/sp_counted_impl.hpp:76
#25 0x0805e62c in boost::detail::sp_counted_base::release (this=0x8d9e788)
    at /usr/include/boost/detail/sp_counted_base_gcc_x86.hpp:145
#26 0x0805e66e in ~shared_count (this=0x8d8b1b0) at /usr/include/boost/detail/shared_count.hpp:159
#27 0x00760b38 in ~shared_ptr (this=0x8d8b1ac) at /usr/include/boost/shared_ptr.hpp:106
#28 0x00769906 in ~Elf_Reader (this=0x8d8b1a8) at ../../../../src/io/input/File_Readers/Elf/Elf_Reader_T.cpp:44
#29 0x00760ffa in boost::checked_delete<libreverse::elf_module::Elf_Reader<32u> > (x=0x8d8b1a8)
    at /usr/include/boost/checked_delete.hpp:34
#30 0x0076ff35 in boost::detail::sp_counted_impl_p<libreverse::elf_module::Elf_Reader<32u> >::dispose (this=0x8d84410)
    at /usr/include/boost/detail/sp_counted_impl.hpp:76
#31 0x0805e62c in boost::detail::sp_counted_base::release (this=0x8d84410)
    at /usr/include/boost/detail/sp_counted_base_gcc_x86.hpp:145
#32 0x0805e66e in ~shared_count (this=0x8d8acd8) at /usr/include/boost/detail/shared_count.hpp:159
#33 0x00760a78 in ~shared_ptr (this=0x8d8acd4) at /usr/include/boost/shared_ptr.hpp:106
#34 0x00766ff7 in ~pair (this=0x8d8acd0)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_pair.h:69
#35 0x00767053 in __gnu_cxx::new_allocator<std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> > >::destroy (this=0xbff1b343, __p=0x8d8acd0)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/ext/new_allocator.h:107
#36 0x007672f1 in std::_Rb_tree<std::string, std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> >, std::_Select1st<std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> > >, std::less<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> > > >::destroy_node (this=0x8d8b184,
    __p=0x8d8acc0) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:391
#37 0x00767384 in std::_Rb_tree<std::string, std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> >, std::_Select1st<std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> > >, std::less<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<libreverse::io::File_Reader> > > >::_M_erase (this=0x8d8b184,
    __x=0x8d8acc0) at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:1266
#38 0x00767447 in ~_Rb_tree (this=0x8d8b184)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_tree.h:578
#39 0x007674a3 in ~map (this=0x8d8b184)
    at /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_map.h:93
#40 0x0075fbb0 in ~Reader_Factory (this=0x8d8b180) at Reader_Factory.cpp:16
#41 0x007612b8 in boost::checked_delete<libreverse::io::Reader_Factory> (x=0x8d8b180)
    at /usr/include/boost/checked_delete.hpp:34
#42 0x0076ff79 in boost::detail::sp_counted_impl_p<libreverse::io::Reader_Factory>::dispose (this=0x8d8b018)
    at /usr/include/boost/detail/sp_counted_impl.hpp:76
#43 0x0805e62c in boost::detail::sp_counted_base::release (this=0x8d8b018)
    at /usr/include/boost/detail/sp_counted_base_gcc_x86.hpp:145
#44 0x0805e66e in ~shared_count (this=0x868890) at /usr/include/boost/detail/shared_count.hpp:159
#45 0x00760a52 in ~shared_ptr (this=0x86888c) at /usr/include/boost/shared_ptr.hpp:106
#46 0x0075fab4 in __tcf_1 () at Reader_Factory.cpp:14
#47 0x47bdcbe9 in __cxa_finalize () from /lib/libc.so.6
#48 0x006b4303 in __do_global_dtors_aux () from /usr/local/lib/libreverse.so.0
#49 0x0079cb2c in _fini () from /usr/local/lib/libreverse.so.0
#50 0x47ba2572 in _dl_fini () from /lib/ld-linux.so.2
#51 0x47bdc939 in exit () from /lib/libc.so.6
#52 0x47bc6f34 in __libc_start_main () from /lib/libc.so.6
#53 0x0805cf41 in _start ()


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net