segfault in TaskBrowser

Hi,

I'm new to orocos and just trying to familiarize myself with how it works. I've tried to create two simple components, each with one unbuffered input and output. The first component just adds an offset to the input value, and the second component multiplies it by a gain.

When I try to play with it in TaskBrowser, it seems to be working at first. I can connect to the Data_R input port of MyOffsetTask and give it a value, and the output is correctly value+offset. If I then cd gain_task, it too is properly multiplying that by its gain. The issue is when I switch back to the offset task (cd offset_task) and try to change the value again, I'm getting a segmentation fault. I'm reconnecting to the input port (.connect Data_R) because the connection seems to be lost when I switch over to a different component. Does connecting to the same port twice not work, or is there something wrong with my code? (Code is below)

Thanks for reading.

#include <rtt/os/main.h>
#include <ocl/TaskBrowser.hpp>
#include <rtt/PeriodicActivity.hpp>
#include <rtt/Ports.hpp>
#include <stdio.h>
#include <assert.h>
 
using namespace RTT;
 
/* Test component applies a P-gain to unbuffered input */
class MyGainTask : public TaskContext
{
    Attribute<double> gain;
    ReadDataPort<double> indatPort;
    WriteDataPort<double> outdatPort;
 
public:
    MyGainTask(std::string name) : TaskContext(name), gain("gain",2.0), indatPort("channel"), outdatPort("Data_W")
    {
        this->attributes()->addAttribute( &gain );
        this->ports()->addPort( &indatPort, "Input Data Port");
        this->ports()->addPort( &outdatPort, "Output Data Port");
    }
 
    bool configureHook()
    {
        return true;
    }
 
    bool startHook()
    {
        return true;
    }
 
    void updateHook()
    {
        outdatPort.Set( gain.get() * indatPort.Get() );
    }
 
    void stopHook()
    {
    }
 
    void cleanupHook()
    {
    }
};
 
/* Test component to add an offset to incoming unbuffered data */
class MyOffsetTask : public TaskContext
{
    Attribute<double> offset;
    ReadDataPort<double> indatPort;
    WriteDataPort<double> outdatPort;
 
public:
    MyOffsetTask(std::string name) : TaskContext(name), offset("offset",-1.0), indatPort("Data_R"), outdatPort("channel")
    {
        this->attributes()->addAttribute( &offset );
        this->ports()->addPort( &indatPort, "Input Data Port");
        this->ports()->addPort( &outdatPort, "Output Data Port");
    }
 
    bool configureHook()
    {
        return true;
    }
 
    bool startHook()
    {
        return true;
    }
 
    void updateHook()
    {
        outdatPort.Set( offset.get() + indatPort.Get() );
    }
 
    void stopHook()
    {
    }
 
    void cleanupHook()
    {
    }
};
 
int ORO_main(int argc, char** argv)
{
    // Create the two tasks, operating in sync
    TaskContext* g_task = new MyGainTask("gain_task");
    TaskContext* o_task = new MyOffsetTask("offset_task");
    g_task->setActivity( new PeriodicActivity( 5, 0.01) );
    o_task->setActivity( new PeriodicActivity( 5, 0.01) );
 
    // Start the tasks
    g_task->start();
    o_task->start();
 
    // Connect the two tasks
    o_task->ports()->getPort("channel")->connectTo( g_task->ports()->getPort("channel") );
    connectPeers( o_task, g_task );
 
    // Set up a TaskBrowser for interaction with the user
    OCL::TaskBrowser browser(o_task);
    browser.loop();
 
    // End the tasks
    g_task->stop();
    o_task->stop();
 
    return 0;
}

segfault in TaskBrowser

On Jun 11, 2009, at 11:47 , ndamore [..] ... wrote:

> Hi,
>
> I'm new to orocos and just trying to familiarize myself with how it
> works. I've tried to create two simple components, each with one
> unbuffered input and output. The first component just adds an
> offset to the input value, and the second component multiplies it by
> a gain.
>
> When I try to play with it in TaskBrowser, it seems to be working at
> first. I can connect to the Data_R input port of MyOffsetTask and
> give it a value, and the output is correctly value+offset. If I
> then cd gain_task, it too is properly multiplying that by its gain.
> The issue is when I switch back to the offset task (cd offset_task)
> and try to change the value again, I'm getting a segmentation
> fault. I'm reconnecting to the input port (.connect Data_R) because
> the connection seems to be lost when I switch over to a different
> component. Does connecting to the same port twice not work, or is
> there something wrong with my code? (Code is below)
>
> Thanks for reading.
>
> &#10;&gt; #include &lt;rtt/os/main.h&gt;&#10;&gt; #include &lt;ocl/TaskBrowser.hpp&gt;&#10;&gt; #include &lt;rtt/PeriodicActivity.hpp&gt;&#10;&gt; #include &lt;rtt/Ports.hpp&gt;&#10;&gt; #include &lt;stdio.h&gt;&#10;&gt; #include &lt;assert.h&gt;&#10;&gt;&#10;&gt; using namespace RTT;&#10;&gt;&#10;&gt; /* Test component applies a P-gain to unbuffered input */&#10;&gt; class MyGainTask : public TaskContext&#10;&gt; {&#10;&gt;    Attribute&lt;double&gt; gain;&#10;&gt;  ReadDataPort&lt;double&gt; indatPort;&#10;&gt;  WriteDataPort&lt;double&gt; outdatPort;&#10;&gt;&#10;&gt; public:&#10;&gt;      MyGainTask(std::string name) : TaskContext(name), gain(&quot;gain&quot;,2.0),  &#10;&gt; indatPort(&quot;channel&quot;), outdatPort(&quot;Data_W&quot;)&#10;&gt;        {&#10;&gt;              this-&gt;attributes()-&gt;addAttribute( &amp;gain );&#10;&gt;           this-&gt;ports()-&gt;addPort( &amp;indatPort, &quot;Input Data Port&quot;);&#10;&gt;            this-&gt;ports()-&gt;addPort( &amp;outdatPort, &quot;Output Data Port&quot;);&#10;&gt;  }&#10;&gt;&#10;&gt;     bool configureHook()&#10;&gt;   {&#10;&gt;              return true;&#10;&gt;   }&#10;&gt;&#10;&gt;     bool startHook()&#10;&gt;       {&#10;&gt;              return true;&#10;&gt;   }&#10;&gt;&#10;&gt;     void updateHook()&#10;&gt;      {&#10;&gt;              outdatPort.Set( gain.get() * indatPort.Get() );&#10;&gt;        }&#10;&gt;&#10;&gt;     void stopHook()&#10;&gt;        {&#10;&gt;      }&#10;&gt;&#10;&gt;     void cleanupHook()&#10;&gt;     {&#10;&gt;      }&#10;&gt; };&#10;&gt;&#10;&gt; /* Test component to add an offset to incoming unbuffered data */&#10;&gt; class MyOffsetTask : public TaskContext&#10;&gt; {&#10;&gt;  Attribute&lt;double&gt; offset;&#10;&gt;        ReadDataPort&lt;double&gt; indatPort;&#10;&gt;  WriteDataPort&lt;double&gt; outdatPort;&#10;&gt;&#10;&gt; public:&#10;&gt;      MyOffsetTask(std::string name) : TaskContext(name),  &#10;&gt; offset(&quot;offset&quot;,-1.0), indatPort(&quot;Data_R&quot;), outdatPort(&quot;channel&quot;)&#10;&gt;         {&#10;&gt;              this-&gt;attributes()-&gt;addAttribute( &amp;offset );&#10;&gt;                 this-&gt;ports()-&gt;addPort( &amp;indatPort, &quot;Input Data Port&quot;);&#10;&gt;            this-&gt;ports()-&gt;addPort( &amp;outdatPort, &quot;Output Data Port&quot;);&#10;&gt;  }&#10;&gt;&#10;&gt;     bool configureHook()&#10;&gt;   {&#10;&gt;              return true;&#10;&gt;   }&#10;&gt;&#10;&gt;     bool startHook()&#10;&gt;       {&#10;&gt;              return true;&#10;&gt;   }&#10;&gt;&#10;&gt;     void updateHook()&#10;&gt;      {&#10;&gt;              outdatPort.Set( offset.get() + indatPort.Get() );&#10;&gt;      }&#10;&gt;&#10;&gt;     void stopHook()&#10;&gt;        {&#10;&gt;      }&#10;&gt;&#10;&gt;     void cleanupHook()&#10;&gt;     {&#10;&gt;      }&#10;&gt; };&#10;&gt;&#10;&gt; int ORO_main(int argc, char** argv)&#10;&gt; {&#10;&gt;         // Create the two tasks, operating in sync&#10;&gt;     TaskContext* g_task = new MyGainTask(&quot;gain_task&quot;);&#10;&gt;   TaskContext* o_task = new MyOffsetTask(&quot;offset_task&quot;);&#10;&gt;       g_task-&gt;setActivity( new PeriodicActivity( 5, 0.01) );&#10;&gt;      o_task-&gt;setActivity( new PeriodicActivity( 5, 0.01) );&#10;&gt;&#10;&gt;     // Start the tasks&#10;&gt;     g_task-&gt;start();&#10;&gt;    o_task-&gt;start();&#10;&gt;&#10;&gt;   // Connect the two tasks&#10;&gt;       o_task-&gt;ports()-&gt;getPort(&quot;channel&quot;)-&gt;connectTo( g_task-&gt;ports()- &#10;&gt; &gt;getPort(&quot;channel&quot;) );&#10;&gt;   connectPeers( o_task, g_task );&#10;&#10;Replace the task-&gt;ports() line with&#10;&#10;       connectPorts( o_task, g_task );&#10;&#10;for starters.&#10;&#10;Your updateHook()&#039;s should be virtual, BTW.&#10;&#10;What does a gdb backtrace of the seg fault show?&#10;&#10;Simplify the problem, and take out the unecessary stuff (eg Data_R  &#10;port).&#10;&#10;Cheers&#10;Stephen

segfault in TaskBrowser

Thanks for the replies. Yes, I was using '.connect' and switching to plain DataPort types gets me around the issue.

I don't have much experience with gdb, but here's a backtrace. I changed the updateHooks to virtual and replaced o_task->ports()->... with connectPorts(...) as suggested.

ndamore@woodstock:~/projects$ gdb ./test3
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run
Starting program: /home/ndamore/projects/test3 
[Thread debugging using libthread_db enabled]
0.004 [ Warning][/home/ndamore/projects/test3::main()] Lowering scheduler type to SCHED_OTHER for non-privileged users..
0.004 [ Warning][/home/ndamore/projects/test3::main()] Forcing priority (5) of thread with SCHED_OTHER policy to 0.
[New Thread 0xb75166c0 (LWP 18995)]
[New Thread 0xb7515b90 (LWP 18998)]
0.007 [ Warning][/home/ndamore/projects/test3::main()] Lowering scheduler type to SCHED_OTHER for non-privileged users..
0.007 [ Warning][/home/ndamore/projects/test3::main()] Forcing priority (5) of thread with SCHED_OTHER policy to 0.
   Switched to : gain_task
 
  This console reader allows you to browse and manipulate TaskContexts.
  You can type in a command, event, method, expression or change variables.
  (type 'help' for instructions)
    TAB completion and HISTORY is available ('bash' like)
 
 In Task gain_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :cd offset_task
   Switched to : offset_task
 
 In Task offset_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :.connect
 
TaskBrowser connects to all ports of offset_task
 
 In Task offset_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :leave
 
 Watching Task offset_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :Data_R.Set(12)
      Got :Data_R.Set(12)
 = (void)              
 
 Watching Task offset_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :cd gain_task
   Switched to : gain_task
 
 Watching Task gain_task[R]. (Status of last Command : none )
 (type 'ls' for context info) :
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7515b90 (LWP 18998)]
0xffffffff in ?? ()
(gdb) bt
#0  0xffffffff in ?? ()
#1  0x0805c0bc in RTT::WriteDataPort<double>::Set ()
#2  0x0805c1b9 in MyOffsetTask::updateHook ()
#3  0xb7af0e52 in RTT::ExecutionEngine::step ()
   from /usr/local/lib/liborocos-rtt-gnulinux.so.1.8
#4  0xb79f31d8 in RTT::PeriodicActivity::step ()
   from /usr/local/lib/liborocos-rtt-gnulinux.so.1.8
#5  0xb7ac3a2e in RTT::TimerThread::step ()
   from /usr/local/lib/liborocos-rtt-gnulinux.so.1.8
#6  0xb7b120c1 in RTT::OS::periodicThread ()
   from /usr/local/lib/liborocos-rtt-gnulinux.so.1.8
#7  0xb77fe4fb in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#8  0xb765de5e in clone () from /lib/tls/i686/cmov/libc.so.6
(gdb) 

segfault in TaskBrowser

On Thu, Jun 11, 2009 at 22:52, <ndamore [..] ...> wrote:
> Thanks for the replies.  Yes, I was using '.connect' and switching to plain DataPort types gets me around the issue.
>
> I don't have much experience with gdb, but here's a backtrace.  I changed the updateHooks to virtual and replaced o_task->ports()->... with connectPorts(...) as suggested.

Thanks for the info, I created a bug report on
https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=670

Peter

segfault in TaskBrowser

On Thu, Jun 11, 2009 at 17:47, <ndamore [..] ...> wrote:
> Hi,
>
> I'm new to orocos and just trying to familiarize myself with how it works.  I've tried to create two simple components, each with one unbuffered input and output.  The first component just adds an offset to the input value, and the second component multiplies it by a gain.
>
> When I try to play with it in TaskBrowser, it seems to be working at first.  I can connect to the Data_R input port of MyOffsetTask and give it a value, and the output is correctly value+offset.  If I then cd gain_task, it too is properly multiplying that by its gain.  The issue is when I switch back to the offset task (cd offset_task) and try to change the value again, I'm getting a segmentation fault.  I'm reconnecting to the input port (.connect Data_R) because the connection seems to be lost when I switch over to a different component.  Does connecting to the same port twice not work, or is there something wrong with my code? (Code is below)

Probably you've hit a bug. I'm assuming here that you used the
'.connect' feature of the taskbrowser ?

You can work around that by using plain DataPort<double> types which
you can then directly write, without doing the .connect trickery. That
should keep you away from these crashes for now.

Sylvain, If you'd be reading this, how did you test your components
with the new data port (InputPort) branch ? Could you write values to
InputPorts from the taskbrowser ?

Peter