PySide Bugzilla Closed for New Bugs

PySide is now a Qt Add-on and uses the Qt Project's JIRA Bug Tracker instead of this Bugzilla instance. This Bugzilla is left for reference purposes.

Bug 1086 - generatorrunner segfault processing #include <boost/signal.hpp>
: generatorrunner segfault processing #include <boost/signal.hpp>
Status: RESOLVED FIXED
Product: PySide
Classification: Unclassified
Component: ApiExtractor
: HEAD
: PC Linux
: P2 normal
Assigned To: Paulo Alcantara
:
:
:
  Show dependency treegraph
 
Reported: 2011-12-07 21:57 EET by Dave Hershberger
Modified: 2012-01-05 02:30 EET (History)
9 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Hershberger 2011-12-07 21:57:23 EET
I'm porting code from wxWidgets to Qt, and the old SWIG python binding scheme
seemed inappropriate for for Qt, so I switched to PySide and Shiboken.  Our
code uses boost signals and slots, and trying to minimize effort I have not
(yet) translated all the boost signals into Qt signals.

Shiboken works for me to generate bindings to a few of my classes, but when I
got to the first class that uses boost signals, it started crashing during
binding generation.

Here is my global.h, trimmed to just the failing part.

#undef QT_NO_STL
#undef QT_NO_STL_WCHAR

#ifndef NULL
#define NULL 0
#endif

#include "pyside_global.h"

#include <QtCore/QtCore>
#include <QtGui/QtGui>

#include <boost/signal.hpp>

Without the #include <boost/signal.hpp> it works fine.

The problem seems to lie in an infinite recursion of rpp::pp::handle_include()
in apiextractor-0.10.9/parser/rpp/pp-engine-bits.h.  I looked at the crash in
gdb and the stack was very very tall, filled only with calls to that function.

Here is the top of that tall stack:

#40891 0x00007ffff78d75d6 in __gnu_cxx::__normal_iterator<char*, std::string>
rpp::pp::handle_include<__gnu_cxx::__normal_iterator<char*, std::string>,
rpp::pp_output_iterator<std::string> >(bool,
__gnu_cxx::__normal_iterator<char*, std::string>,
__gnu_cxx::__normal_iterator<char*, std::string>,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40892 0x00007ffff78d75d6 in __gnu_cxx::__normal_iterator<char*, std::string>
rpp::pp::handle_include<__gnu_cxx::__normal_iterator<char*, std::string>,
rpp::pp_output_iterator<std::string> >(bool,
__gnu_cxx::__normal_iterator<char*, std::string>,
__gnu_cxx::__normal_iterator<char*, std::string>,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40893 0x00007ffff78d79bc in char const* rpp::pp::handle_include<char const*,
rpp::pp_output_iterator<std::string> >(bool, char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40894 0x00007ffff78d705b in void rpp::pp::operator()<char const*,
rpp::pp_output_iterator<std::string> >(char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40895 0x00007ffff78d7339 in void
rpp::pp::file<rpp::pp_output_iterator<std::string> >(_IO_FILE*,
rpp::pp_output_iterator<std::string>) ()
   from /usr/lib/libapiextractor.so.0.10
#40896 0x00007ffff78d7ac9 in char const* rpp::pp::handle_include<char const*,
rpp::pp_output_iterator<std::string> >(bool, char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40897 0x00007ffff78d705b in void rpp::pp::operator()<char const*,
rpp::pp_output_iterator<std::string> >(char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40898 0x00007ffff78d7339 in void
rpp::pp::file<rpp::pp_output_iterator<std::string> >(_IO_FILE*,
rpp::pp_output_iterator<std::string>) ()
   from /usr/lib/libapiextractor.so.0.10
#40899 0x00007ffff78d7ac9 in char const* rpp::pp::handle_include<char const*,
rpp::pp_output_iterator<std::string> >(bool, char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40900 0x00007ffff78d705b in void rpp::pp::operator()<char const*,
rpp::pp_output_iterator<std::string> >(char const*, char const*,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40901 0x00007ffff78d7339 in void
rpp::pp::file<rpp::pp_output_iterator<std::string> >(_IO_FILE*,
rpp::pp_output_iterator<std::string>) ()
   from /usr/lib/libapiextractor.so.0.10
#40902 0x00007ffff78d73e1 in void
rpp::pp::file<rpp::pp_output_iterator<std::string> >(std::string const&,
rpp::pp_output_iterator<std::string>) () from /usr/lib/libapiextractor.so.0.10
#40903 0x00007ffff78c7180 in preprocess(QString const&, QFile&, QStringList
const&) () from /usr/lib/libapiextractor.so.0.10
#40904 0x00007ffff78c7848 in ApiExtractor::run() () from
/usr/lib/libapiextractor.so.0.10
#40905 0x000000000040a200 in main ()

Additionally I get a ton of warnings like this:

** WARNING unknown directive '#' at /usr/include/boost/preprocessor/cat.hpp:8
** WARNING unknown directive '#' at /usr/include/boost/preprocessor/cat.hpp:9
** WARNING unknown directive '#' at /usr/include/boost/preprocessor/cat.hpp:10
** WARNING unknown directive '#' at /usr/include/boost/preprocessor/cat.hpp:11

before the crash.  I think they don't matter, the boost author was just putting
a "#" at the beginning of every line of the files (for extra beauty, I guess).

Also a few warnings like this:

** WARNING expected ``)'' = 1002
** WARNING expected ``)'' = 1002
** WARNING expected ``)'' = 1002

and some others with 40 instead of 1002.  For those messages it is not clear
where the problem is coming from, since they don't have a filename.

I see a similar behavior when I #include <boost/thread.hpp>, but instead of
crashing it seems to get into a broken state where it doesn't see any more of
my class definitions after that #include.

I know boost pushes hard on the C++ preprocessor, and apiextractor seems to be
essentially duplicating a bunch of the preprocessor's functionality, so it's
not surprising there would be trouble.
Comment 1 Paulo Alcantara 2012-01-05 02:30:56 EET
Hi,

Boost headers typically include the character '#' at the beginning of
any line and just do nothing elese with that unnamed directive. So
as that's not actually an error, rather that's just a just-do-nothing
directive, APIExtractor will just ignore this and go on.

About the messages as "** WARNING expected ``)'' = 1002", that's why
some macro declared in any boost header includes extra parentheses to
support any compiler and keep backward compatibility. So APIExtractor
won't parse that kind of macro properly.

There's still a problem when using #include directives and passing
macros as arguments rather than a path to the header file. Instead
of asserting this issue we'll print a warning message about this issue
(boost headers mostly do this), and APIExtractor does not support this.

Thanks for the report!

This bug has been fixed on APIExtractor commit
4fb16e2a0b4906dc4353e0c8b4463f27aa5f8863.