[C++-sig] crashes on functions with std::string arguments

Thomas Schipolowski thomas.schipolowski at tu-berlin.de
Tue Apr 5 13:28:55 CEST 2005


 Hello,
 I am using Python 2.3 and Boost_1_32_0 with VC6 on Windows 2000. I
experience crashes due to heap corruption when a function or method with a
std::string argument is called. The same problem is also triggered by the
extract<std::string> facility.
 The following test code reproduces both conditions:

#include <string>
#include <boost/python.hpp>
using namespace boost::python;

int test1(std::string s) {
            return s.end() - s.begin();
}

int test2(object o) {
            extract<std::string> extr(o);
            if (extr.check()) {
                        std::string s(extr());
                        return s.end() - s.begin();
            } else {
                        return -1;
            }
}

BOOST_PYTHON_MODULE(test)
{
            def("test1", test1);
            def("test2", test2);
}

The error will not be immediately apparent until the extension is compiled
in debug mode. Calling any of the above functions from python will then
(always) pop up a message saying  "Debug Assertion _CrtIsValidHeapPtr()
failed". When compiled without debug, the function calls may succeed many
times before an "unidentifyable C++ exception" is reported. The interpreter
will segfault at this point or later on, depending on memory usage.

Now I saw this message
http://mail.python.org/pipermail/c++-sig/2005-April/008760.html on the list
which seems related. With regard to the explanation given there (multiple
versions of the C++ runtime library on windows) I agree that this is a
possible reason in my case, as the problem mysteriously went away when I
switched from my Win 2000 box at work to a Win XP Laptop. But yesterday I
tried on a third computer (also XP) and there it crashed the same as on Win
2000. However, I think the standard library is statically linked in my case.
(But I am not sure how to check and control this in the VC-IDE.)

I tried to dig into the source with a debugger, but couldn't find a solution
so far. Details are below. I would be glad about any advice on how to
correct this or work around it.

Many thanks,
Thomas Schipolowski


The debugger shows me that the error happens at the point where the
temporary std::string object stored in
rvalue_from_python_data<>::storage.bytes is destroyed. (In case of the
test1() function this happens when
detail::caller_arity<1>::impl<>::operator() finishes. In the test2()
function it is the destruction of the extr variable when test2() returns.)
Further inside the std::string destructor, the problem is apparently caused
by the destructor trying to deallocate the internal character buffer. At
this point I thought there might be something wrong with the copy-on-write
implementation of std::string. In fact, the string s in test2() is destroyed
first, deleting its buffer, and then it crashes when the string contained in
extr is destroyed, again deleting its buffer. But I am not sure if there is
actually anything shared between both string objects. From what I saw in the
debugger, it appears that the constructor of s initializes its pointer to
the character buffer of a temporary string which is created as return value
of extract_rvalue<T>::operator(). The buffer address of s is different from
the buffer of the string in extract_rvalue<>.m_data.storage.bytes. I have no
idea what can be wrong here.







More information about the Cplusplus-sig mailing list