2017-03-05 4 views
0

Ich entwickle das Back-End einer App und ich versuche, meinen C++ - Code in Python zu wickeln. Ich habe Boost Python3 verwendet, um C++ mit Python zu verbinden. Ich bin in der Lage, eine gemeinsame Bibliothek zu bekommen und sie von Python aus aufzurufen. Im Moment funktioniert alles.Speicherverlust in C++ Python-Wrapper

Das Problem tritt auf, wenn ich versuche, diese Bibliothek zu exportieren. Ich würde gerne in der Lage sein, es von einem anderen Ort oder Computer zu verwenden, ohne den C++ Code neu zu kompilieren.

Um diese Bibliothek zu testen, verschiebe ich die Bibliothek einfach in einen anderen Ordner mit seinen Abhängigkeiten und überprüfe mit ldd, ob alle Abhängigkeiten aufgelöst sind (kein Problem dafür).

Dann versuche ich ein Objekt von Python3 aufrufen. Zu Beginn kann ich viele Funktionen ausführen, aber wenn ich python3 beende und neu starte, beginne ich mit einigen Segmentierungsfehlern, Speicherbeschädigungen, ... Als Beispiel: * Fehler in `python3 ': free() : ungültig nächste Größe (normal): 0x0000000001ebeb50 *

Ich habe versucht, Valgrind zu verwenden, um Speicherlecks zu finden. Mein Programm in C++ hat keinen Speicherverlust. Wenn ich Valgrind mit meinem Python-Code versuche, habe ich keine Lecks für die Bibliothek in ihrem ursprünglichen Ordner. Nachdem jedoch die Bibliothek bewegt habe, beginne ich, wie einige undichte Stellen zu haben:

Invalid write of size 4 ==22695== at 0x6DCA0F9: Test::Test(std::string, std::string, std::string, int) (maintests.cpp:71) ==22695== by 0x6933E5B: boost::python::objects::value_holder<Test>::value_holder(_object*) (value_holder.hpp:137) ==22695== by 0x6934D8D: boost::python::objects::make_holder<0>::apply<boost::python::objects::value_holder<ritmo::Test>, boost::mpl::joint_view<boost::python::detail::drop1<boost::python::detail::type_list<boost::python::optional<std::string, std::string, std::string, int, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_> >, boost::python::optional<std::string, std::string, std::string, int, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_> > >::execute(_object*) (make_holder.hpp:94) ==22695== by 0x693924E: _object* boost::python::detail::invoke<int, void (*)(_object*), boost::python::arg_from_python<_object*> >(boost::python::detail::invoke_tag_<true, false>, int const&, void (*&)(_object*), boost::python::arg_from_python<_object*>&) (invoke.hpp:81) ==22695== by 0x6936942: boost::python::detail::caller_arity<1u>::impl<void (*)(_object*), boost::python::default_call_policies, boost::mpl::vector2<void, _object*> >::operator()(_object*, _object*) (caller.hpp:223) ==22695== by 0x6935D88: boost::python::objects::caller_py_function_impl<boost::python::detail::caller<void (*)(_object*), boost::python::default_call_policies, boost::mpl::vector2<void, _object*> > >::operator()(_object*, _object*) (py_function.hpp:38) ==22695== by 0x71CE139: boost::python::objects::function::call(_object*, _object*) const (in /usr/lib/x86_64-linux-gnu/libboost_python-py34.so.1.54.0) ==22695== by 0x71CE4A7: ??? (in /usr/lib/x86_64-linux-gnu/libboost_python-py34.so.1.54.0) ==22695== by 0x71D8742: boost::python::handle_exception_impl(boost::function0<void>) (in /usr/lib/x86_64-linux-gnu/libboost_python-py34.so.1.54.0) ==22695== by 0x71CCDB2: ??? (in /usr/lib/x86_64-linux-gnu/libboost_python-py34.so.1.54.0) ==22695== by 0x53493C: ??? (in /usr/bin/python3.4) ==22695== by 0x4F14F9: PyObject_Call (in /usr/bin/python3.4) ==22695== Address 0x6333fe0 is 16 bytes after a block of size 32 in arena "client"

ich mit diesem Problem bin zu kämpfen. Jede Idee oder Tipps sind mehr als willkommen.

Vielen Dank

+2

Sie müssen eine kleine in sich geschlossene Probe bereitstellen - eine [MCVE] (http://stackoverflow.com/help/mcve). – tambre

+0

Ich kann den Fehler nicht mit einem kleinen Beispiel reproduzieren ... Irgendwelche Ratschläge? – Antoine

+0

Verwenden Sie einen Debugger. Sehen Sie, wo die Speicherbeschädigung passiert. Begnügen Sie sich nicht mit einer Workaround, die Sie nicht einmal verstehen. – tambre

Antwort

0

Ich habe endlich den segfault gefunden. Der Header, den ich für das Kompilieren des Programms verwendete, unterschied sich von dem, den die Bibliothek verwendete. Ein Klassenmitglied wurde nicht deklariert und daher wurde diesem Mitglied kein Speicher zugewiesen.