Coin 3.1.3, SoQt 1.5.0, Python 2.6.6 and Qt 4.6.3

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Coin 3.1.3, SoQt 1.5.0, Python 2.6.6 and Qt 4.6.3

Krzysztof Trzciński
I spent the whole day yesterday debugging why after upgrading Coind from 2.5.0 to 3.1.3 I get segfault when I try to
launch qtcoinviewer. I did not find what exactly the problem is and I cannot recreate the problem on a smaller working
example. However the good news is that I found a rather simple way to get OpenRAVE running with the newest versions of
libraries and Python 2.6 (possibly Python 3 also, but I did not test this). If you are interested only in solution then
here it is:
export LD_PRELOAD=/usr/lib/libCoin.so
and then run python with your OpenRAVE script.
What it does is it forces the use of libCoin functions before the libexpat (and they have a few in common).

Below is a bit about what I have found about this problem. The purpose of that is maybe someone with greater knowledge
and some spare time will be able to point out any mistakes I made (I have a very rough knowledge of how does gcc linker
work) or will be able to provide some ideas on how to solve this in a better way.
I also post this on OpenRAVE mailing list as it is quite OpenRAVE (or Python if you will) specific problem.

Simple use of gdb with debugging symbols compiled in libraries and sources for them told me that the segfault occurs in
XML_ParserFree(). I found that XML_* functions are from expat library.
As program crashed on initialization of SoQt window I thought I will give a shot the simples working example from SoQt
documentation (http://doc.coin3d.org/SoQt/). And it worked. So I got gdb to work once again to see what is happening.
After some time spent on step-by-step walking through the both programs and checking the arguments of corresponding
functions I saw minor differences. This lead me to checking where does XML_ParserFree (and other XML_*) function(s) come
from.

When I debugged the crashed OpenRAVE python script I got:
(gdb) info symbol XML_ParserFree
XML_ParserFree in section .text of /usr/lib/libexpat.so.1

when I run the same command for the example code from SoQt docs:
(gdb) info symbol XML_ParserFree
XML_ParserFree in section .text of /usr/lib/libCoin.so.60

After some digging in Coin sources I found xmlparser.c file. From comments I learned that they copied the expat parser
and modified it a little. This might explain why there was a segfault: implementation of those functions in libexat is
different from what libCoin expects.
The reason why the standalone example works is that it doesn't link with expat, so all XML_* symbols are those from
libCoin. And the reason why the qtcoinviewer plugin doesn't work is that Python loads symbols from libexpat and when
qtcoinviewer is loaded it pulls libCoin, but all XML_* functions are already defined by libexpat. So we end up using the
ones that Python pulled from libexpat first and this leads to conclusion (*) that Coin cannot work with XML_* functions
provided by libexpat.

This way I got the solution given at the beginning.
I thought to myself that it might be a good idea to create a simple working example to file a bug for Coin developers.
Unfortunately I could not reproduce this problem. I have created a simple program based on SoQt example:

--- <main.cpp> ---
  #include <expat.h>
  #include <stdio.h>
  #include <dlfcn.h>

  extern "C"
  {
    typedef void (*view_t)(int, char**);
  }

  int
  main(int argc, char ** argv)
  {
    XML_Parser p =XML_ParserCreate("UTF-8");
    XML_ParserFree(p);

    void * handle = dlopen("./view.so", RTLD_NOW);
    printf("handle: %p\n", handle);

    view_t view = (view_t) dlsym(handle, "view");
    printf("view_sym: %p\n", view);
    view(argc, argv);

    dlclose(handle);

    return 0;
  }
--- </main.cpp> ---

--- <view.cpp> ---
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoSeparator.h>

extern "C"
{
    void view(int argc, char ** argv);
}

void view(int argc, char ** argv)
{
    for(unsigned int i = 0; i < argc; ++i)
        puts(argv[i]);
    // Initializes SoQt library (and implicitly also the Coin and Qt
    // libraries). Returns a top-level / shell Qt window to use.
    QWidget * mainwin = SoQt::init(argc, argv, argv[0]);

    // Make a dead simple scene graph by using the Coin library, only
    // containing a single yellow cone under the scenegraph root.
    SoSeparator * root = new SoSeparator;
    root->ref();

    SoBaseColor * col = new SoBaseColor;
    col->rgb = SbColor(1, 1, 0);
    root->addChild(col);

    root->addChild(new SoCone);

    // Use one of the convenient SoQt viewer classes.
    SoQtExaminerViewer * eviewer = new SoQtExaminerViewer(mainwin);
    eviewer->setSceneGraph(root);
    eviewer->show();

    // Pop up the main window.
    SoQt::show(mainwin);
    // Loop until exit.
    SoQt::mainLoop();

    // Clean up resources.
    delete eviewer;
    root->unref();
    SoQt::done();
}
--- </view.cpp> ---

--- <Makefile> ---
all:
                g++ -shared -fPIC view.cpp  `pkg-config --libs --cflags SoQt` -o view.so -g -lpthread
                g++ main.cpp -lexpat -ldl -g `pkg-config --cflags SoQt` -lpthread
--- </Makefile> ---

Compiling this should give us the same situation as with the Python loading the plug-in. And it does:
(gdb) info symbol XML_ParserFree
XML_ParserFree in section .text of /usr/lib/libexpat.so.1

Unfortunately the application doesn't crash.
If I remove the -lexpat I get:
(gdb) info symbol XML_ParserFree
XML_ParserFree in section .text of /usr/lib/libCoin.so.60

So everything works as expected except the application doesn't crash with libexpat linked.

This means that libCoin can use any of those two implementations, so my conclusion marked above with (*) was incorrect.
The only thing I can think of now (and which would make more sense regarding the segfault) is that in the case of Python
and qtcoinviewer plug-in we get mixed calls to XML_* functions. Some of them are made to implementation in libexpat and
some are made to libCoin. But this is where my knowledge of linker and dynamic libraries loading ends and I could only
guess why this could happen.

As I have found a workaround my urge to find out what exactly is wrong is much smaller than it was before, but I am open
to any suggestions and ideas on how to investigate this problem further.

------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
Openrave-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/openrave-users