Yarp: Python bindings for RFModule lead to segfault when calling yarp.Network.fini()

Created on 13 Dec 2016  路  9Comments  路  Source: robotology/yarp

Hi,
When playing with the Yarp bindings, I have found that a module segfaults when calling yarp.Network.fini(), but only if a RFModule is used.
Minimum working example:

#!/usr/bin/env python

import yarp
import time
import sys

print sys.argv

class TestMod(yarp.RFModule):
    def configure(self, rf):
        moduleName = rf.check("name", yarp.Value("test")).asString()
        self.setName(moduleName)
        self.count = 0
        return True

    def respond(self, command, reply):
        return True

    def interruptModule(self):
        print "Interrupt"
        return True

    def close(self):
        print "Close"
        return True

    def getPeriod(self):
        return 1.0

    def updateModule(self):
        time.sleep(0.5)
        self.count = self.count + 1
        print self.count
        if self.count < 3:
            return True
        else:
            return False


yarp.Network.init()

rf = yarp.ResourceFinder()
rf.setVerbose(True);
rf.setDefaultContext("test");
rf.setDefaultConfigFile("config.ini");
rf.configure(sys.argv)

mod = TestMod()
mod.runModule(rf)

yarp.Network.fini()

This leads to the following segfault:

||| did not find config.ini
yarp: cannot read from config.ini
1
2
3
[INFO]RFModule closing.
Close
[INFO]RFModule finished.

Program received signal SIGSEGV, Segmentation fault.
__new_sem_wait (sem=0x8) at sem_wait.c:26
26  sem_wait.c: No such file or directory.
(gdb) thread apply all bt

Thread 1 (Thread 0x7ffff7f9f700 (LWP 4660)):
#0  __new_sem_wait (sem=0x8) at sem_wait.c:26
#1  0x00007ffff521a34c in yarp::os::impl::ThreadImpl::isRunning() ()
   from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/../../libYARP_OS.so.1
#2  0x00007ffff5219bf9 in ThreadCallbackAdapter::close() ()
   from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/../../libYARP_OS.so.1
#3  0x00007ffff52199a2 in yarp::os::Thread::stop() () from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/../../libYARP_OS.so.1
#4  0x00007ffff51e092e in yarp::os::RFModule::~RFModule() ()
   from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/../../libYARP_OS.so.1
#5  0x00007ffff654e69b in _wrap_delete_RFModule () from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/_yarp.so
#6  0x00000000004b0cb3 in PyObject_Call ()
#7  0x00000000004b97fa in PyObject_CallFunctionObjArgs ()
#8  0x00007ffff643e610 in SwigPyObject_dealloc () from /usr/local/src/robot/install/yarp/lib/python2.7/dist-packages/_yarp.so
#9  0x00000000004fd4e6 in ?? ()
#10 0x00000000004a0d22 in PyDict_SetItem ()
#11 0x0000000000502bf3 in _PyModule_Clear ()
#12 0x000000000050275c in PyImport_Cleanup ()
#13 0x0000000000500489 in Py_Finalize ()
#14 0x000000000049df2f in Py_Main ()
#15 0x00007ffff7811830 in __libc_start_main (main=0x49dab0 <main>, argc=2, argv=0x7fffffffd588, init=<optimised out>, fini=<optimised out>, 
    rtld_fini=<optimised out>, stack_end=0x7fffffffd578) at ../csu/libc-start.c:291
#16 0x000000000049d9d9 in _start ()

When removing the last line (yarp.Network.fini()), all is good.

It seems like that in ThreadImpl this code is causing the problem - it seems like threadMutex is deleted somewhere and then cannot be accessed anymore.

bool ThreadImpl::isRunning()
{
    threadMutex->wait();
    bool b = active;
    threadMutex->post();
    return b;
}

Best, Tobi

YARP v2.3.68 Bindings YARP v2.3.68.1 Bug Low Fixed Minor

All 9 comments

By the way, this also happens when creating a yarp.Network object:

yn = yarp.Network()

rf = yarp.ResourceFinder()
rf.setVerbose(True);
rf.setDefaultContext("test");
rf.setDefaultConfigFile("config.ini");
rf.configure(sys.argv)

mod = TestMod()
mod.runModule(rf)

Remainder: when we fix this bug we should add the regression test (that is basically already attached to the bug report) in https://github.com/robotology/yarp/tree/master/bindings/tests/python .

Just to confirm: I can reproduce the error when calling yarp.Network.fini(). I hadn't called this function beforehand, so I didn't experience the problem. But I guess I'm supposed to call this function prior to leaving main.

@frank-foerster: Yes, at least in C++ it's good practice to either call yarp.Network.fini() or create a yarp.Network object which automatically takes care of this when it's being destroyed.

@traversaro: Maybe the code snippet can also be added as example on how to use RFModule from Python.

I think that the RFModule might be using some object coming from the network initialization, but without calling init and fini internally.
The order of destruction of the objects appears to be different from the "C++" order

  1. init
  2. RFModule::RFModule
  3. fini
  4. RFModule::~RFModule

or using the network

  1. Network::Network
  2. RFModule::RFModule
  3. Network::~Network
  4. RFModule::~RFModule

Perhaps this is due to the %feature("director") yarp::os::RFModule; in the .i?

Adding this seems to fix the issue as well:
I want to investigate this a little bit better before committing this, though.

diff --git a/src/libYARP_OS/src/RFModule.cpp b/src/libYARP_OS/src/RFModule.cpp
index 2894ed3..461879b 100644
--- a/src/libYARP_OS/src/RFModule.cpp
+++ b/src/libYARP_OS/src/RFModule.cpp
@@ -350,6 +350,7 @@ static void handler_sigbreak(int sig) {


 RFModule::RFModule() {
+    yarp::os::Network::initMinimum();
     implementation = new RFModuleHelper(*this);
     stopFlag = false;

@@ -376,6 +377,7 @@ RFModule::~RFModule() {
         delete &HELPER(implementation);
         implementation = YARP_NULLPTR;
     }
+    yarp::os::Network::finiMinimum();
 }


@drdanz have you committed these lines? Have they resolved the problem?

Nope, this was never committed, I don't remember why... @Tobias-Fischer Have you tried the patch above? Did this solve your problem?

Hi @drdanz,
Yes the above patch fixes the problem. All working fine in that case :). Is it okay for you to commit that patch to yarp?

Best, Tobi

I think it is. I will test it a little bit more and commit it in the next few days

Was this page helpful?
0 / 5 - 0 ratings