Serialization demo program crashes trying to free an unallocated block

Hi, Warning: noob inside. I am new to boost, and quite a bit rusty with C+ +, having spent the past few years with other languages. Nonetheless. I downloaded, built and installed Boost 1.40 just fine on Mac OS X 10.6 (Snow Leopard). I set up a XCode 3.2 project to compile and run the demo.cpp program delivered with the Serialization library. It crashes deep inside this line: restore_schedule(new_schedule, filename.c_str()); GDB gives the following error message: malloc: *** error for object 0x1000581a0: pointer being freed was not allocated The stack crawl shows: #0 0x7fff81202ff6 in __kill #1 0x7fff812a4072 in abort #2 0x7fff811bb095 in free #3 0x7fff836031e8 in std::string::reserve #4 0x7fff836032fe in std::string::append #5 0x10028ccac in boost ::archive::text_iarchive_impl<boost::archive::text_iarchive>::load at text_iarchive_impl.ipp:55 #6 0x100024a5e in boost ::archive::load_access::load_primitive<boost::archive::text_iarchive, std::string> at iserializer.hpp:109 #7 0x100024a83 in boost ::archive ::detail::load_non_pointer_type<boost::archive::text_iarchive, std::string>::load_primitive::invoke at iserializer.hpp:332 #8 0x100024aa8 in boost ::archive ::detail::load_non_pointer_type<boost::archive::text_iarchive, std::string>::invoke at iserializer.hpp:417 #9 0x100024acd in boost::archive::load<boost::archive::text_iarchive, std::string> at iserializer.hpp:542 #10 0x100024afe in boost ::archive ::detail ::common_iarchive <boost::archive::text_iarchive>::load_override<std::string> at common_iarchive.hpp:61 #11 0x100024b2b in boost ::archive ::basic_text_iarchive <boost::archive::text_iarchive>::load_override<std::string> at basic_text_iarchive.hpp:62 #12 0x100024b59 in boost ::archive ::text_iarchive_impl <boost::archive::text_iarchive>::load_override<std::string> at text_iarchive.hpp:66 #13 0x100024b8c in boost ::archive ::detail ::interface_iarchive <boost::archive::text_iarchive>::operator>><std::string> at interface_iarchive.hpp:61 #14 0x100024bc3 in boost ::archive ::detail ::interface_iarchive <boost::archive::text_iarchive>::operator&<std::string> at interface_iarchive.hpp:68 #15 0x100026688 in bus_stop_corner::serialize<boost::archive::text_iarchive> at main.cpp: 123 #16 0x1000266c3 in boost::serialization::access::serialize<boost::archive::text_iarchive, bus_stop_corner> at access.hpp:109 and so on... The last frame for which I have source code is #5. There the crashes occurs in the following routine: template<class Archive> BOOST_ARCHIVE_DECL(void) text_iarchive_impl<Archive>::load(std::string &s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(size); // <============== crash here if(0 < size) is.read(&(*s.begin()), size); } In that frame, s is the empty string (its internal buffer points to a 0 byte), and size is 11. Suspecting a bug in OS X std::string class, I checked that the following program works fine: int main() { std::string s; std::size_t size = 11; std::cout << s << std::endl; s.resize(size); std::cout << s << std::endl; } So I tried to follow the stack up tracking the string object to see where and how it was created. I lost track of it in frame #15 on the following line: ar & street1 & street2; Note that this is back to the sample code. I decided to split that line into two lines, and surely now the crashes occurs there: ar & street1; I'm going to go on tracing through that, but maybe this rings a bell with someone, that would save me time... I can post more info if needed. Best regards and thanks, Jean-Denis

I tried it on my system with both msvc-7.11 and gcc-4.3.2 (under cygwin) and it worked fine. I used bjam to build and test it. Robert Ramey Jean-Denis Muys wrote:
Hi,
Warning: noob inside. I am new to boost, and quite a bit rusty with C+ +, having spent the past few years with other languages.
Nonetheless.
I downloaded, built and installed Boost 1.40 just fine on Mac OS X 10.6 (Snow Leopard).
I set up a XCode 3.2 project to compile and run the demo.cpp program delivered with the Serialization library.
It crashes deep inside this line:
restore_schedule(new_schedule, filename.c_str());
GDB gives the following error message:
malloc: *** error for object 0x1000581a0: pointer being freed was not allocated
The stack crawl shows:
#0 0x7fff81202ff6 in __kill #1 0x7fff812a4072 in abort #2 0x7fff811bb095 in free #3 0x7fff836031e8 in std::string::reserve #4 0x7fff836032fe in std::string::append #5 0x10028ccac in boost
archive::text_iarchive_impl<boost::archive::text_iarchive>::load at text_iarchive_impl.ipp:55 #6 0x100024a5e in boost archive::load_access::load_primitive<boost::archive::text_iarchive, std::string> at iserializer.hpp:109 #7 0x100024a83 in boost archive detail::load_non_pointer_type<boost::archive::text_iarchive, std::string>::load_primitive::invoke at iserializer.hpp:332 #8 0x100024aa8 in boost archive detail::load_non_pointer_type<boost::archive::text_iarchive, std::string>::invoke at iserializer.hpp:417 #9 0x100024acd in boost::archive::load<boost::archive::text_iarchive, std::string> at iserializer.hpp:542 #10 0x100024afe in boost archive detail common_iarchive <boost::archive::text_iarchive>::load_override<std::string> at common_iarchive.hpp:61 #11 0x100024b2b in boost archive basic_text_iarchive <boost::archive::text_iarchive>::load_override<std::string> at basic_text_iarchive.hpp:62 #12 0x100024b59 in boost archive text_iarchive_impl <boost::archive::text_iarchive>::load_override<std::string> at text_iarchive.hpp:66 #13 0x100024b8c in boost archive detail interface_iarchive <boost::archive::text_iarchive>::operator>><std::string> at interface_iarchive.hpp:61 #14 0x100024bc3 in boost archive detail interface_iarchive <boost::archive::text_iarchive>::operator&<std::string> at interface_iarchive.hpp:68 #15 0x100026688 in bus_stop_corner::serialize<boost::archive::text_iarchive> at main.cpp: 123 #16 0x1000266c3 in boost::serialization::access::serialize<boost::archive::text_iarchive, bus_stop_corner> at access.hpp:109
and so on...
The last frame for which I have source code is #5. There the crashes occurs in the following routine:
template<class Archive> BOOST_ARCHIVE_DECL(void) text_iarchive_impl<Archive>::load(std::string &s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(size); // <============== crash here if(0 < size) is.read(&(*s.begin()), size); }
In that frame, s is the empty string (its internal buffer points to a 0 byte), and size is 11.
Suspecting a bug in OS X std::string class, I checked that the following program works fine:
int main() { std::string s; std::size_t size = 11; std::cout << s << std::endl; s.resize(size); std::cout << s << std::endl; }
So I tried to follow the stack up tracking the string object to see where and how it was created. I lost track of it in frame #15 on the following line:
ar & street1 & street2;
Note that this is back to the sample code.
I decided to split that line into two lines, and surely now the crashes occurs there:
ar & street1;
I'm going to go on tracing through that, but maybe this rings a bell with someone, that would save me time... I can post more info if needed. Best regards and thanks,
Jean-Denis

Well, I spent a large number of hours since my original message, and while I learned a lot, I could not solve my problem and I am about to give up using Boost. Here is what I managed to find out: - first an foremost, the example works fine when compiled and run from the terminal using the following command: c++ demo.cpp -o demo /usr/local/lib/libboost_serialization.dylib - the crash happens when running the example from the XCode IDE. Since my real project is developed using XCode, this is a show-stopper. - clearly, this is a Mac specific issue. I suspect something stupid, such as a build setting or something, but I could not find what. I posted requests for help on the XCode mailing list, but judging by the suggestions I got, Boost is not very popular with Mac developers. - So if somebody has managed to set up a working project under XCode (version 3.2 preferably), I'd be really interested in that. Now to the crash: I downloaded the source code the Mac version of the standard C++ library and for its malloc/free routine. Using that, I managed to reconstruct what's happening: 1- Boost allocate a new object of the sample code class bus_stop_corner. It's properly constructed, and its strings are initialized to empty std::string 2- Before reading the text for the street1 std::string, Boost calls std::string:resize() to size it to the correct length (11 in the sample run). 3- resize() sees that the new size is larger than the previous size (which was 0), and so calls std::string:append() to append some memory at the end. 4- append() sees that the new length is larger than the old string capacity and calls td::string:reserve() 5- reserve() clones the old string into a newly allocated larger buffer, of the size requested, and then calls _M_dispose() on the old buffer. Here is its source code: template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res) { if (__res != this->capacity() || _M_rep()->_M_is_shared()) { // Make sure we don't shrink below the current size if (__res < this->size()) __res = this->size(); const allocator_type __a = get_allocator(); _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); _M_rep()->_M_dispose(__a); _M_data(__tmp); } } 6- _M_rep()->_M_dispose() calls _M_destroy() 7- _M_destroy() calls deallocate() (a method on the allocator) on the _M_rep() buffer 8- deallocate() calls the standard operator delete on its argument. void deallocate(pointer __p, size_type) { ::operator delete(__p); } 9- delete calls the standard C routine free(), which is defined in malloc.c: void free(void *ptr) { malloc_zone_t *zone; size_t size; if (!ptr) return; zone = find_registered_zone(ptr, &size); if (!zone) { malloc_printf("*** error for object %p: pointer being freed was not allocated\n" "*** set a breakpoint in malloc_error_break to debug\n", ptr); malloc_error_break(); if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION| SCALABLE_MALLOC_ABORT_ON_ERROR))) abort(); } else if (zone->version >= 6 && zone->free_definite_size) malloc_zone_free_definite_size(zone, ptr, size); else malloc_zone_free(zone, ptr); } 10- the error occurs because free() cannot find the zone from which the string buffer was allocated. At this point I give up: I checked that the std::string whose buffer is deallocated was indeed properly constructed, ie that its buffer was allocated in a normal way: pointer allocate(size_type __n, const void* = 0) { if (__builtin_expect(__n > this->max_size(), false)) std::__throw_bad_alloc(); return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } To go further I would need to get deep into the malloc implementation. Since the same code is running fine when built from the terminal, I suspect this would be fruitless. I'm open to suggestions, but a this point, I throw in the towel. Jean-Denis On Sep 20, 2009, at 21:04 , Robert Ramey wrote:
I tried it on my system with both msvc-7.11 and gcc-4.3.2 (under cygwin) and it worked fine. I used bjam to build and test it.
Robert Ramey
Jean-Denis Muys wrote:
Hi,
Warning: noob inside. I am new to boost, and quite a bit rusty with C+ +, having spent the past few years with other languages.
Nonetheless.
I downloaded, built and installed Boost 1.40 just fine on Mac OS X 10.6 (Snow Leopard).
I set up a XCode 3.2 project to compile and run the demo.cpp program delivered with the Serialization library.
It crashes deep inside this line:
restore_schedule(new_schedule, filename.c_str());
GDB gives the following error message:
malloc: *** error for object 0x1000581a0: pointer being freed was not allocated
The stack crawl shows:
#0 0x7fff81202ff6 in __kill #1 0x7fff812a4072 in abort #2 0x7fff811bb095 in free #3 0x7fff836031e8 in std::string::reserve #4 0x7fff836032fe in std::string::append #5 0x10028ccac in boost

Jean-Denis Muys wrote:
Well, I spent a large number of hours since my original message, and while I learned a lot, I could not solve my problem and I am about to give up using Boost.
Here is what I managed to find out:
- first an foremost, the example works fine when compiled and run from the terminal using the following command:
c++ demo.cpp -o demo /usr/local/lib/libboost_serialization.dylib
- the crash happens when running the example from the XCode IDE. Since my real project is developed using XCode, this is a show-stopper.
Well, clearly it's a build issue. So this problem will likely come up using any boost library. I don't think that tracing into the serialization code is going to be very helpful. The only thing I could suggest is to detemine what the command line XCode IDE is using and compare it to the one used above or with the one generated by bjam. Robert Ramey

Hi, Following up on my crash of the serialization demo program in XCode I found its cause but I need help to fix it. It turns out that XCode defines _GLIBCXX_DEBUG=1 _GLIBCXX_DEBUG_PEDANTIC=1 in its debugging targets. This was the source of the crash. Googling for the reason was not straightforward, but I eventually found this, on the Gnu website:
To use the libstdc++ debug mode, compile your application with the compiler flag -D_GLIBCXX_DEBUG. Note that this flag changes the sizes and behavior of standard class templates such as std::vector, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units.
This page is at http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch30s03.html The standard build of Boost does not define _GLIBCXX_DEBUG I suppose and that explains the crash. So what's the best way to fix this? 1- As I have been suggested a couple times, removing the define from XCode's debugging target works, but I contend this is not the right way, as I do not wish to do without the debugging scaffolding provided by my tools, at least if there is a better way. 2- A better idea is to have a build of Boost compiled with _GLIBCXX_DEBUG defined. 3- Even better, have Boost works both with _GLIBCXX_DEBUG and without _GLIBCXX_DEBUG in the same build. The way the Gnu standard C++ Library achieves this is to conditionally compile code depending on _GLIBCXX_DEBUG not in the implementation files, but only in the headers. When the impact cannot be avoided in the implementation files, it defines two variations of the same standard class, a normal and a debug version, switching from one to the other in the header file. Could Boost evolve in that direction? My vote is in. But that's not for today. So coming back to idea #2, I started to dive into the Boost build system to achieve it, but my first try was not a success. I am really not very experienced with the Unix way, nor with the Boost build system, so maybe someone can save me from learning the intricacies. Here is what I did: 1- First build the standard Boost: sudo ./bjam release This worked. 2- Then build the debug Boost: sudo ./bjam debug define=_GLIBCXX_DEBUG=1 define=_GLIBCXX_DEBUG_PEDANTIC=1 This worked, but I could not confirm that both defines were used. Did I do it the right way? Does the debug target already define those two symbols? Could it? Also I'm not sure which object files are debug and release. To take as an example the serialization objects, I now have four files in my lib directory: $ ls -la *serial* -rw-r--r-- 1 root wheel 6616488 Sep 23 16:31 libboost_serialization.a -rwxr-xr-x 1 root wheel 807368 Sep 23 16:31 libboost_serialization.dylib -rw-r--r-- 1 root wheel 4871728 Sep 23 16:31 libboost_wserialization.a -rwxr-xr-x 1 root wheel 612296 Sep 23 16:31 libboost_wserialization.dylib What is this "w" prefix supposed to mean? 3- Install both builds: sudo ./bjam debug release install This fails with errors such as: error: Duplicate name of actual target: <p/usr/local/ lib>libboost_date_time.dylib So did the the first two command also install Boost? Can the two build coexist? Again, the answers are possibly in the doc. I have started studying it, but this takes time. I guess I'd eventually find the answers to these questions on my own, but I'd appreciate some boost (hmmm...). Best regards, Jean-Denis Muys On Sep 20, 2009, at 22:29 , Robert Ramey wrote:
Jean-Denis Muys wrote:
Well, I spent a large number of hours since my original message, and while I learned a lot, I could not solve my problem and I am about to give up using Boost.
Here is what I managed to find out:
- first an foremost, the example works fine when compiled and run from the terminal using the following command:
c++ demo.cpp -o demo /usr/local/lib/libboost_serialization.dylib
- the crash happens when running the example from the XCode IDE. Since my real project is developed using XCode, this is a show-stopper.
Well, clearly it's a build issue. So this problem will likely come up using any boost library. I don't think that tracing into the serialization code is going to be very helpful.
The only thing I could suggest is to detemine what the command line XCode IDE is using and compare it to the one used above or with the one generated by bjam.
Robert Ramey
participants (2)
-
Jean-Denis Muys
-
Robert Ramey