s-nakaoka / choreonoid

An integrated graphical robotics application framework
http://choreonoid.org
Other
94 stars 58 forks source link

20160526のビルドでBodyRTCの読み込みで落ちる #104

Closed YoheiKakiuchi closed 7 years ago

YoheiKakiuchi commented 8 years ago

debでインストールしている環境で、20160526のビルドにおいて、BodyRTCの読み込みでchoreonoidが落ちてしまいます。

あまり深入りできておりませんが、問題は最新のOpenRTMのソースにあるように思うのですが、現象が確認できるのがchoreonoidですので、こちらに報告させてもらいます。

20160526のopenrtm-aistを使って、ソースからコンパイルしても同じようになっております。 (ros-indigo-openrtm-aistをつかってコンパイルすると問題は起こりません) 最近の変更で何かありましたでしょうか? @n-ando

以下、Debugフラグをつけてコンパイルしたchoreonoidでのgdbの結果をお送りします。

(gdb) run
Starting program: /usr/local/choreonoid/bin/choreonoid /usr/local/choreonoid/share/choreonoid-1.5/project/OpenRTM-PA10Pickup.cnoid
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe4fd6700 (LWP 8995)]
[New Thread 0x7fffdffff700 (LWP 8996)]
[New Thread 0x7fffdcabd700 (LWP 8997)]
[New Thread 0x7fffd7fff700 (LWP 8998)]
[New Thread 0x7fffd77ae700 (LWP 8999)]
[Thread 0x7fffd7fff700 (LWP 8998) exited]
[New Thread 0x7fffd7fff700 (LWP 9002)]
[New Thread 0x7fffc32cc700 (LWP 9003)]
[New Thread 0x7fffc2a7b700 (LWP 9004)]
[New Thread 0x7fffc222a700 (LWP 9010)]
Loading body customizer "/home/leus/ros/indigo/src/rtm-ros-robotics/rtmros_choreonoid/hrpsys_choreonoid/JAXONCustomizer.so" for JAXON_JVRC
[New Thread 0x7fffc022b700 (LWP 9011)]
[Thread 0x7fffc022b700 (LWP 9011) exited]
[New Thread 0x7fffbf9da700 (LWP 9012)]
[Thread 0x7fffbf9da700 (LWP 9012) exited]

Program received signal SIGSEGV, Segmentation fault.
0x00007fffc8202922 in _CORBA_Sequence<double>::_CORBA_Sequence (
    this=0x7fffffffa038, s=...)
    at /usr/include/omniORB4/seqTemplatedecls.h:236
236       pd_buf[i] = s.pd_buf[i];
(gdb) bt
#0  0x00007fffc8202922 in _CORBA_Sequence<double>::_CORBA_Sequence (
    this=0x7fffffffa038, s=...)
    at /usr/include/omniORB4/seqTemplatedecls.h:236
#1  0x00007fffc81fc011 in _CORBA_Unbounded_Sequence<double>::_CORBA_Unbounded_Sequence (this=0x7fffffffa038, s=...)
    at /usr/include/omniORB4/seqTemplatedecls.h:325
#2  0x00007fffc81f1e8d in _CORBA_Unbounded_Sequence_w_FixSizeElement<double, 8, 8>::_CORBA_Unbounded_Sequence_w_FixSizeElement (this=0x7fffffffa038, s=...)
    at /usr/include/omniORB4/seqTemplatedecls.h:566
#3  0x00007fffc81f260f in RTC::TimedDoubleSeq::TimedDoubleSeq (
    this=0x7fffffffa030)
    at /usr/include/openrtm-1.1/rtm/idl/BasicDataType.hh:446
#4  0x00007fffc81f27e8 in RTC::OutPort<RTC::TimedDoubleSeq>::OutPort (
    this=0x14f52e8, name=0x14c41c8 "q", value=..., __in_chrg=<optimized out>, 
    __vtt_parm=<optimized out>) at /usr/include/openrtm-1.1/rtm/OutPort.h:141
#5  0x00007fffc81ea986 in cnoid::SensorStateOutPortHandler::SensorStateOutPortHandler (this=0x14f52c0, info=...)
    at /home/leus/src/choreonoid/src/OpenRTMPlugin/VirtualRobotPortHandler.cpp:26
#6  0x00007fffc81e145e in cnoid::VirtualRobotRTC::createOutPortHandler (
    this=0x15003d0, portInfo=...)
    at /home/leus/src/choreonoid/src/OpenRTMPlugin/VirtualRobotRTC.cpp:111
#7  0x00007fffc81e1266 in cnoid::VirtualRobotRTC::createPorts (
    this=0x15003d0, bridgeConf=0x14c0ed0)
    at /home/leus/src/choreonoid/src/OpenRTMPlugin/VirtualRobotRTC.cpp:81
#8  0x00007fffc81be965 in cnoid::BodyRTCItem::createRTC (this=0x14c8ce0, 
    body=...)
    at /home/leus/src/choreonoid/src/OpenRTMPlugin/BodyRTCItem.cpp:197
#9  0x00007fffc81bfae4 in cnoid::BodyRTCItem::onPositionChanged (
    this=0x14c8ce0)
    at /home/leus/src/choreonoid/src/OpenRTMPlugin/BodyRTCItem.cpp:277
#10 0x00007ffff784aba4 in cnoid::Item::callSlotsOnPositionChanged (
    this=0x14c8ce0) at /home/leus/src/choreonoid/src/Base/Item.cpp:236
#11 0x00007ffff784aaf4 in cnoid::Item::doInsertChildItem (this=0x114f150, 
    item=0x14c8ce0, nextItem=0x0, isManualOperation=false)
    at /home/leus/src/choreonoid/src/Base/Item.cpp:207
#12 0x00007ffff784a812 in cnoid::Item::addChildItem (this=0x114f150, 
    item=0x14c8ce0, isManualOperation=false)
    at /home/leus/src/choreonoid/src/Base/Item.cpp:122
#13 0x00007ffff78ee7ac in cnoid::ItemTreeArchiverImpl::restoreItemIter (
Python Exception <class 'IndexError'> list index out of range: 
    this=0x973a20, archive=..., parentItem=0x114f150, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:274
#14 0x00007ffff78eeacc in cnoid::ItemTreeArchiverImpl::restoreItemIter (
Python Exception <class 'IndexError'> list index out of range: 
    this=0x973a20, archive=..., parentItem=0x10e4820, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:295
#15 0x00007ffff78eeacc in cnoid::ItemTreeArchiverImpl::restoreItemIter (
Python Exception <class 'IndexError'> list index out of range: 
    this=0x973a20, archive=..., parentItem=0x973bf0, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:295
#16 0x00007ffff78eeacc in cnoid::ItemTreeArchiverImpl::restoreItemIter (
Python Exception <class 'IndexError'> list index out of range: 
    this=0x973a20, archive=..., parentItem=0x973bf0, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:295
#17 0x00007ffff78edd16 in cnoid::ItemTreeArchiverImpl::restore (
Python Exception <class 'IndexError'> list index out of range: 
    this=0x973a20, archive=..., parentItem=0x973bf0, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:183
#18 0x00007ffff78edcbb in cnoid::ItemTreeArchiver::restore (this=0x9738a0, 
Python Exception <class 'IndexError'> list index out of range: 
    archive=0x10b83e0, parentItem=0x973bf0, 
    optionalPlugins=std::set with 0 elements)
    at /home/leus/src/choreonoid/src/Base/ItemTreeArchiver.cpp:172
#19 0x00007ffff77c50fa in cnoid::ProjectManagerImpl::loadProject (
    this=0x9738a0, 
    filename="/usr/local/choreonoid/share/choreonoid-1.5/project/OpenRTM-PA10Pickup.cnoid", isInvokingApplication=true)
    at /home/leus/src/choreonoid/src/Base/ProjectManager.cpp:287
#20 0x00007ffff77c64ea in cnoid::ProjectManagerImpl::onSigOptionsParsed (
    this=0x9738a0, v=...)
    at /home/leus/src/choreonoid/src/Base/ProjectManager.cpp:462
#21 0x00007ffff77db444 in boost::_mfi::mf1<void, cnoid::ProjectManagerImpl, boost::program_options::variables_map&>::operator() (this=0x905af8, p=0x9738a0, 
    a1=...) at /usr/include/boost/bind/mem_fn_template.hpp:165
#22 0x00007ffff77d8d27 in boost::_bi::list2<boost::_bi::value<cnoid::ProjectManagerImpl*>, boost::arg<1> >::operator()<boost::_mfi::mf1<void, cnoid::ProjectManagerImpl, boost::program_options::variables_map&>, boost::_bi::list1<boost::program_options::variables_map&> > (this=0x905b08, f=..., a=...)
    at /usr/include/boost/bind/bind.hpp:313
#23 0x00007ffff77d400e in boost::_bi::bind_t<void, boost::_mfi::mf1<void, cnoid::ProjectManagerImpl, boost::program_options::variables_map&>, boost::_bi::list2<boost::_bi::value<cnoid::ProjectManagerImpl*>, boost::arg<1> > >::operator()<boost::program_options::variables_map> (this=0x905af8, a1=...)
    at /usr/include/boost/bind/bind_template.hpp:32
#24 0x00007ffff77d0d64 in boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf1<void, cnoid::ProjectManagerImpl, boost::program_options::variables_map&>, boost::_bi::list2<boost::_bi::value<cnoid::ProjectManagerImpl*>, boost::arg<1> > >, void, boost::program_options::variables_map&>::invoke (function_obj_ptr=..., a0=...)
    at /usr/include/boost/function/function_template.hpp:153
#25 0x00007ffff78d1c2d in boost::function1<void, boost::program_options::variables_map&>::operator() (this=0x905af0, a0=...)
    at /usr/include/boost/function/function_template.hpp:767
#26 0x00007ffff78d179e in cnoid::ArgSet1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> >::call<cnoid::signal_private::SlotHolder1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> > > (this=0x7fffffffc670, slot=0x905ad0)
    at /home/leus/src/choreonoid/src/Util/SignalTemplate.h:91
#27 0x00007ffff78d1394 in cnoid::signal_private::SlotCallIterator<cnoid::signal_private::SlotHolder1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> >, cnoid::ArgSet1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> > >::operator* (
    this=0x7fffffffc630) at /home/leus/src/choreonoid/src/Util/Signal.h:101
#28 0x00007ffff78d0d3a in cnoid::signal_private::last_value<void>::operator()<cnoid::signal_private::SlotCallIterator<cnoid::signal_private::SlotHolder1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> >, cnoid::ArgSet1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> > > > (this=0x7fffffffc66f, first=..., last=...)
    at /home/leus/src/choreonoid/src/Util/Signal.h:43
#29 0x00007ffff78d0379 in cnoid::Signal1<void, boost::program_options::variables_map&, cnoid::signal_private::last_value<void> >::operator() (
    this=0x7ffff7dd95b0 <cnoid::ExtensionManager::optionManager()::optionManager>, a1=...) at /home/leus/src/choreonoid/src/Util/SignalTemplate.h:217
#30 0x00007ffff78cf9b1 in cnoid::OptionManager::parseCommandLine (
    this=0x7ffff7dd95b0 <cnoid::ExtensionManager::optionManager()::optionManager>, argc=2, argv=0x7fffffffc9b8)
    at /home/leus/src/choreonoid/src/Base/OptionManager.cpp:51
#31 0x00007ffff77bafbf in cnoid::AppImpl::processCommandLineOptions (
    this=0x65d040) at /home/leus/src/choreonoid/src/Base/App.cpp:371
#32 0x00007ffff77bacc4 in cnoid::AppImpl::exec (this=0x65d040)
    at /home/leus/src/choreonoid/src/Base/App.cpp:306
#33 0x00007ffff77bacaa in cnoid::App::exec (this=0x7fffffffc8a0)
    at /home/leus/src/choreonoid/src/Base/App.cpp:300
#34 0x0000000000401259 in main (argc=2, argv=0x7fffffffc9b8)
    at /home/leus/src/choreonoid/src/Choreonoid/main.cpp:24
(gdb) 
n-ando commented 8 years ago

見たところOutPortのコンストラクタあたりで落ちているようなのですが、OpenRTMのshared libraryとOutPort.hを実体化している部分(shared library?実行ファイル?)で、バージョンが違うということはないでしょうか? trunkのOutPort/InPort周りは、ここ1年くらいの間に何度か手を入れてオブジェクトの構造的に互換性がなくなっています。

ros-indigo-openrtm-aist のOpenRTMのバージョン(リビジョン?)はいくつですか?

YoheiKakiuchi commented 8 years ago

ros-indigo-openrtm-aistのバージョンは1.1.0相当で1年以上更新されていません。 gdbの結果は、最新のchoreoonidのソースと20160526のopenrtm-aistのdebでmakeした結果でして、 ros-indigo-openrtm-aistは関係していない部分でchoreonoidが落ちるようになっております。

fkanehiro commented 8 years ago

openrtm-aistをうちのPPAから入れられているということですね。 @n-ando さん、PPAではRELENG_1_1を毎晩ビルドして、deb化しています。なにか関係有りそうでしょうか。 こちらでも同じ現象が起きています。

n-ando commented 8 years ago

そうすると、先日rtm.pyのreadDataPort用に修正した以下の変更が悪さをしているんでしょうかね。 あまり関係なさそうに見えるのですが、、、、

===================================================================
--- OutPort.h   (リビジョン 2722)
+++ OutPort.h   (リビジョン 2723)
@@ -138,6 +138,8 @@
 #endif
         m_value(value), m_onWrite(0), m_onWriteConvert(0)
     {
+      addProperty("dataport.data_value", m_value);
+      m_propValueIndex = NVUtil::find_index(m_profile.properties, "dataport.data_value");
     }

     /*!
@@ -209,6 +211,7 @@
           (*m_onWrite)(value);
           RTC_TRACE(("OnWrite called"));
         }
+      m_profile.properties[m_propValueIndex].value <<= value;

       bool result(true);
       std::vector<const char *> disconnect_ids;
@@ -490,6 +493,8 @@
     coil::TimeMeasure m_cdrtime;

     DataPortStatusList m_status;
+
+    CORBA::Long m_propValueIndex;
   };
 }; // namespace RTC
fkanehiro commented 8 years ago

あれ、これってtrunkだけじゃなくてRELENG_1_1にも入ってるんですか?

n-ando commented 8 years ago

入ってます。本来ならヘッダの修正はマイナーリビジョンには入れないのですが、OutPort.hはクラステンプレートかつfinalなクラスという想定なので、入れてしまっております。rtm.pyのreadDataPortで落ちる件もありましたし。影響のある部分とかありますでしょうか?

fkanehiro commented 8 years ago

いえ、RELENG_1_1の方に入っていないと思っていたので、rtm.pyの修正をしていなかったのですが、こちらにも入ったのであればrtm.pyの修正も取り込ませていただきます。

n-ando commented 8 years ago

でも、Choreonoidに影響があるのであれば、戻したほうがいいのかも。。。 先日お送りしたrtm.pyの修正は新旧どちらのOutPortでも大丈夫ですが。。。

ちなみに、OutPort.hを元に戻したらChoreonoidが落ちる問題は治りませんか?

fkanehiro commented 8 years ago

全く理由がわかりませんが、治りますね。

2016年5月27日 19:07 Noriaki Ando notifications@github.com:

でも、Choreonoidに影響があるのであれば、戻したほうがいいのかも。。。 先日お送りしたrtm.pyの修正は新旧どちらのOutPortでも大丈夫ですが。。。

ちなみに、OutPort.hを元に戻したらChoreonoidが落ちる問題は治りませんか?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/s-nakaoka/choreonoid/issues/104#issuecomment-222109917, or mute the thread https://github.com/notifications/unsubscribe/AAzlyf9jqq83nlIxw6u7HUn2U9lHlM3Kks5qFsJqgaJpZM4InqHy .

n-ando commented 8 years ago

同一プロセス内に存在する、libRTCに関係するバイナリはすべて新しいソースからビルドされたものですか?古いOpenRTMとリンクしているshared objectとかは混ざってませんか?

fkanehiro commented 8 years ago

システム内にlibRTC*.soが1つしかないことを確認しました。不思議ですね。

n-ando commented 8 years ago

OutPort.hのコンストラクタの、

addProperty("dataport.data_value", m_value);

addProperty("dataport.data_value", 0);

にするとどうなりますでしょうか?

fkanehiro commented 8 years ago

動きますね。

fkanehiro commented 8 years ago

m_valueを0にすると動くのがよくわからないのですが、どういうことなんでしょうか?

n-ando commented 8 years ago

上のbacktraceを見ると、CORBAのsequenceのコピーコンストラクタのインデックスでアクセスしている部分で落ちているようなのですが、 pd_buf[i] = s.pd_buf[i];

ここはこの時点ではsequenceのサイズはまだ0のはずで、そもそもこのforループに入らないはずです。 他の場所で、CORBAのsequenceのメンバ変数の領域にaccess violationを起こしている気が。。。 まだ詳しく調べていないのでわかりませんが。。。

ちなみに、手元でこの状況を再現するにはどうすればよろしいですか? OpenRTM対応オプション付きでChoreonoidをとりあえずはコンパイルしてみました。 その後はどうすればよろしいでしょうか?

fkanehiro commented 8 years ago

メモリ破壊だとすると環境によって現象の出方が異なるかもしれませんが、僕の手元の環境では、ChoreonnoidをBUILD_OPENRTM_SAMPLESをONにしてコンパイルして、share/choreonoid-1.5/project/OpenRTM-PA10Pickup.cnoidを開くと問題の箇所で落ちますね。

n-ando commented 8 years ago

ありがとうございます。こちらでも同じような現象を再現できました。 こちらは以下のような環境で、御覧の通り、新しいデータポートでリンクされています。

$ uname -a
Linux ubuntu1404 3.13.0-86-generic #130-Ubuntu SMP Mon Apr 18 18:27:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ strings PA10PickupControllerRTC.so |grep "data_value"
dataport.data_value

以下のように OpenRTM-PA10Pickup.cnoid をロードすると落ちました。 addPropertie() の第2引数に m_value ではない適当な値を入れておくとcore dumpが回避できました。 おそらく、同じ状況が再現できているのだと思います。 今日は時間がななそうなので、明日以降ちょっと追ってみます。

$ ./choreonoid 
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
中止 (コアダンプ)
n-ando commented 8 years ago

原因が分かりました。おそらくメンバーの初期化順の問題です。

VirtualRobotPortHandler.h 内のSensorStateOutPortHandler クラスのメンバーオブジェクトRTC::OutPort<RTC::TimedDoubleSeq> outPort;RTC::TimedDoubleSeq values; の宣言順が逆です。

class SensorStateOutPortHandler : public OutPortHandler
{
public:
    SensorStateOutPortHandler(PortInfo& info);
    virtual void inputDataFromSimulator(BodyRTCItem* bodyRTC);
    virtual void writeDataToPort();
    RTC::OutPort<RTC::TimedDoubleSeq> outPort;
private:
    RTC::TimedDoubleSeq values;
    DataTypeId dataTypeId;
};

コンストラクタでは、outPort(info.portName.c_str(), values) のように呼び出されるのですが、この並び順だとこの時点ではvaluesはまだ初期化されておらず、OutPortのコンストラクタ内では初期化されていない m_value を使用して addProperty("dataport.data_value", m_value); つまり、シーケンスのコピーコンストラクタを呼び出します。

    OutPort(const char* name, DataType& value)
      : OutPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
        m_value(value), m_onWrite(0), m_onWriteConvert(0)
    {
      addProperty("dataport.data_value", m_value);

その際、シーケンス内部の変数も不定のため、コピーコンストラクタでおかしなインデックスの領域を呼び出してしまっているようです。

本来であれば、

class SensorStateOutPortHandler : public OutPortHandler
{
public:
    SensorStateOutPortHandler(PortInfo& info);
    virtual void inputDataFromSimulator(BodyRTCItem* bodyRTC);
    virtual void writeDataToPort();
private:
    RTC::TimedDoubleSeq values; // ここと
public:
    RTC::OutPort<RTC::TimedDoubleSeq> outPort; // ここの順序が重要
private:
    DataTypeId dataTypeId;
};

とするか、コンストラクタで、valuesのコンストラクタを明示的に呼び出してあげる必要があります。

SensorStateOutPortHandler::SensorStateOutPortHandler(PortInfo& info) :
    OutPortHandler(info),
    values(), // ここで明示的に初期化
    outPort(info.portName.c_str(), values)
{
    dataTypeId = info.dataTypeId;
    stepTime = info.stepTime;
}

ただ、後者の方法はコンパイラがWarningを出しますが。。。。いずれの方法も試しましたが、choreonoidは落ちなくなりました。

なお、VirtualRobotPortHandler.h内では、同様の初期化順の問題を抱えているクラスが多数あります。 C++の規約として、クラスのメンバー変数の初期化は宣言された順序で行われる、また初期化子は宣言の順序で記述されなければいけないので、VirtualRobotPortHandler.h/cppを修正しいただく必要があります。

snozawa commented 8 years ago

@n-andoさん、@fkanehiroさん 諸々ありがとうございます。 こちらはVirtualRobotPortHandler.h/cppを更新していただいて、 debがアップデートされれば治りそう、ということでしょうか。 よろしくお願いいたします。

fkanehiro commented 8 years ago

はい、そのはずです。PR #105 を投げました。

snozawa commented 8 years ago

ありがとうございます。

snozawa commented 8 years ago

@YoheiKakiuchi さん こちらの環境でも openrtm_aist をdeb、choreonoidをソースで治ってますでしょうか? また、choreonoid debはいかがでしょうか?

openrtm-aistは1.1.2+20160527+1729+12~ubuntu12.04.1 choreonoidは1.5.0+dfsg+20160531+598+17~ubuntu12.04.1 でdebでいれて、

roslaunch hrpsys_ros_bridge_jvrc jaxon_jvrc_choreonoid.launch TASK:=O1

で落ちるきがします。

YoheiKakiuchi commented 8 years ago

さきほどchoreonoidが更新されて、20160602で修正されたものになっているようです。 ソースからのコンパイル、debでインストールどちらも動いているかと思います。

fkanehiro commented 8 years ago

@n-ando さん、コメントありがとうございました。教えて頂いた方法で、VirtualRobotRTCを生成する時にコケる、ということはなくなったのですが、その後でpythonからコンポーネントをロードして生成して、即座にポートのプロファイルを取ろうとすると、

  File "/home/kanehiro/openrtp/lib/python2.7/dist-packages/hrpsys/rtm.py", line 37, in __init__
    prof = p.get_port_profile()
  File "/usr/lib/python2.7/dist-packages/RTC_idl.py", line 1205, in get_port_profile
    return _omnipy.invoke(self, "get_port_profile", _0_RTC.PortService._d_get_port_profile, args)
omniORB.CORBA.MARSHAL: CORBA.MARSHAL(omniORB.MARSHAL_InvalidEnumValue, CORBA.COMPLETED_NO)

といったエラーが起きます。 一度もwrite()してないポートのプロファイルを取ろうとすると問題がおきる、ということはないでしょうか。

fkanehiro commented 8 years ago

問題の範囲が少し絞れてきました。 データポートのデータ型がOpenRTMに入っている基本的な型の場合は問題ないのですが、自分で定義したRTCの名前空間にはいっていない型の場合にエラーが起きるようです。 スタブが見えてないとかそういうことなんでしょうか。

fkanehiro commented 8 years ago

write()されるとプロファイルが取れるようになるので、スタブが見えてないとかそういうことではなさそう。 問題が起きるのは例えばTimedCameraImageで、enumが使われていはいるけれど、write()する前も初期化はされている。 https://github.com/s-nakaoka/choreonoid/blob/master/src/OpenRTMPlugin/VirtualRobotPortHandler.cpp#L379

fkanehiro commented 8 years ago

https://github.com/s-nakaoka/choreonoid/blob/master/src/OpenRTMPlugin/VirtualRobotPortHandler.cpp#L379 で初期化しても、プロファイルの入っているデータは初期化されてないからだめなのか。

fkanehiro commented 8 years ago

enumを含んだデータ型のデータポートのプロファイルを取得する前には、enumのフィールドを初期化した上で、write()を一度呼んでおく必要がある。 ということのようですね。 う〜ん。 それとポートのプロファイルを取得するたびに画像のような大量のデータも送られる、というのもちょっと気になりますね。 どうしたものでしょうか。n-andoさん。

snozawa commented 8 years ago

@YoheiKakiuchi さん https://github.com/s-nakaoka/choreonoid/issues/104#issuecomment-223296259 のあとupgradeして、途中までは機動するようになりました。 その後、setupLoggerの近辺(落ちている箇所は毎回変わる)で落ちており、 setupLoggerをコメントアウトするときどうするようになりますが、そのようなことはないでしょうか。

choreonoidがdebで1.5.0+dfsg+20160602+599+17~ubuntu12.04.1です。 rtmlaunch hrpsys_choreonoid_tutorials jaxon_red_choreonoid.launch できどうしています。

snozawa commented 8 years ago

@YoheiKakiuchi さん @fkanehiro さん報告の https://github.com/s-nakaoka/choreonoid/issues/104#issuecomment-223300079 がうちでもおきることはないでしょうか。

gdbかけてみた結果をお送りします。

[rtm.py]    Connect seq.lhsensorRef - sh.lhsensorIn (dataflow_type=Push, subscription_type=flush, bufferlength=1, push_rate=1000, push_policy=new)
[rtm.py]    Connect seq.rhsensorRef - sh.rhsensorIn (dataflow_type=Push, subscription_type=flush, bufferlength=1, push_rate=1000, push_policy=new)
[rtm.py]    Connect seq.lfsensorRef - sh.lfsensorIn (dataflow_type=Push, subscription_type=flush, bufferlength=1, push_rate=1000, push_policy=new)
[rtm.py]    Connect seq.rfsensorRef - sh.rfsensorIn (dataflow_type=Push, subscription_type=flush, bufferlength=1, push_rate=1000, push_policy=new)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffc0d48700 (LWP 25813)]
__memmove_ssse3_back ()
    at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1579
1579    ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: No such file or directory.
(gdb) bt
#0  __memmove_ssse3_back ()
    at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1579
#1  0x00007fffd0e8fab7 in cdrMemoryStream::put_octet_array(unsigned char const*, int, omni::alignment_t) () from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#2  0x00007fffd05f4532 in ?? ()
   from /usr/lib/choreonoid-1.5/libCnoidOpenRTMPlugin.so
#3  0x00007fffd05f4d5b in ?? ()
   from /usr/lib/choreonoid-1.5/libCnoidOpenRTMPlugin.so
#4  0x00007fffd12a4142 in CORBA::Any::operator=(CORBA::Any const&) ()
   from /usr/lib/choreonoid-1.5/../libomniDynamic4.so.1
#5  0x00007fffcfe58180 in RTC::PortBase::get_port_profile() ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#6  0x00007fffcfead772 in ?? () from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#7  0x00007fffd0e77d8e in omni::omniOrbPOA::dispatch(omniCallDescriptor&, omniLocalIdentity*) () from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#8  0x00007fffd0e5d507 in omniLocalIdentity::dispatch(omniCallDescriptor&) ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#9  0x00007fffd0e6be67 in omniObjRef::_invoke(omniCallDescriptor&, bool) ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#10 0x00007fffcfeae3df in RTC::_objref_PortService::get_port_profile() ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#11 0x00007fffcfdfa4ee in RTC::PortAdmin::port_prof_collect2::operator()(RTC::_objref_PortService*) () from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#12 0x00007fffcfdf8188 in RTC::PortAdmin::getPortProfileList() const ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#13 0x00007fffcfe08b0e in RTC::RTObject_impl::get_component_profile() ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#14 0x00007fffcfeacf35 in ?? () from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#15 0x00007fffd0e86381 in omniCallHandle::upcall(omniServant*, omniCallDescriptor&) () from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#16 0x00007fffcfead17d in RTC::_impl_RTObject::_dispatch(omniCallHandle&) ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#17 0x00007fffcfeb8533 in OpenRTM::_impl_DataFlowComponent::_dispatch(omniCallHandle&) () from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so
#18 0x00007fffd0e782dd in omni::omniOrbPOA::dispatch(omniCallHandle&, omniLocalIdentity*) () from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#19 0x00007fffd0e5d248 in omniLocalIdentity::dispatch(omniCallHandle&) ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#20 0x00007fffd0ea0b92 in omni::GIOP_S::handleRequest() ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#21 0x00007fffd0ea19d0 in omni::GIOP_S::dispatcher() ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#22 0x00007fffd0e9e3b3 in omni::giopWorker::real_execute() ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#23 0x00007fffd0e9ea2f in omni::giopWorker::execute() ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#24 0x00007fffd0e50425 in omniAsyncWorkerInfo::run() ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#25 0x00007fffd0e50b4f in omniAsyncWorker::run(void*) ()
   from /usr/lib/choreonoid-1.5/../libomniORB4.so.1
#26 0x00007fffd0b8b4d3 in omni_thread_wrapper ()
   from /usr/lib/choreonoid-1.5/../libomnithread.so.3
#27 0x00007ffff3b3ae9a in start_thread (arg=0x7fffc0d48700)
    at pthread_create.c:308
#28 0x00007ffff5fd536d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#29 0x0000000000000000 in ?? ()
(gdb) 
n-ando commented 8 years ago

データの初期化の問題は、

      addProperty("dataport.data_value", 0);

にしておけば、とりあえず未初期化のデータは来なくなるのでエラーは避けられそうですがどうでしょう。

あと、画像のような大きいデータがPortProfileに入っているのは問題ですね。将来的には、データをプロファイルからとるかどうかはオプションで選択できるようにしようと思っているのですが。

やはり、ワンショットでデータを取得する別の方法を考えたほうがいいのかな。 例えば、ポート接続で corba_cdr の代わりに oneshot という型を用意しておいて、connect() を呼ぶとConnectorProfile::properties の中にデータが入っているとか。CORBA呼び出しが2回になってしまいますが、最初のやり方よりはまだだいぶ速いと思います。ただ、connect部分の処理はデータ型非依存にかかれているので、これをやろうとすると実装は汚くなってしまいますね。

それよりも、readDataPort 等のグローバルな関数は、rtm.pyのRTcomponentのメンバー関数にできないもんでしょうか?そうすれば、頻繁にconnectすることなくいつでもデータを取ることができると思うのですが。

fkanehiro commented 8 years ago

@n-ando さん、Pull型の通信について教えて頂けないでしょうか。 OutPortの中のデータを引っ張り出してくるものではなく、コネクタ内のデータを引っ張りだしてくるもの、という理解でよろしいでしょうか。上のコメントはコネクタをどこかのタイミングで作っておいて、保持しておけば読み出しの瞬間にコネクタに入っているデータが即座に読み出せるので、待つ必要がない、ということでしょうか。 またコネクタのバッファというのは実体はどこにあるのでしょうか。送信側?受信側?Pull型の場合はパブリッシャはないと思いますが、この場合はバッファはどちらかだけにあるのでしょうか?

snozawa commented 8 years ago

(こちらの手元の状況ですが)

choreonoid-data_1.5.0+dfsg+20160509+585+17~ubuntu12.04.1_all.deb
choreonoid_1.5.0+dfsg+20160509+585+17~ubuntu12.04.1_amd64.deb
libcnoid-dev_1.5.0+dfsg+20160509+585+17~ubuntu12.04.1_amd64.deb
libcnoid1_1.5.0+dfsg+20160509+585+17~ubuntu12.04.1_amd64.deb

のように過去のものに戻したら動いているようです。

fkanehiro commented 8 years ago

@n-ando さん、addPropertyの値を0にすると問題なさそうです。 addPropertyの値を0にするか、ポートプロファイルにデータを入れる機能を削除するか、どちらかをお願いします。

n-ando commented 8 years ago

Pull型の接続ですが、以下のような構造になっています。

onExecute() ->[ ][ ][ ][ ][ ][ ]----○ ⊃-----[読み出し側 rtm.py readDataPort]
           buffer   provider consumer
       |<--- OutPort connector ---->|

バッファはOutPortのconnector側にあります。

ご推察のとおりPull型ではInPort側が明示的に読みに行くのでpublisherは有りません。onExecute() が Pull connectorのバッファにひたすら書き込みに行くだけです。

addProperty の第2引数を 0 にするのはbranchに入れることが可能ですので、そのようにします。

fkanehiro commented 8 years ago

launchpadでのビルドが以下のようなエラーで失敗しています。 手元で試してもエラーが起きないのですが、何か考えられる原因はありますでしょうか。

make[3]: Entering directory `/«BUILDDIR»/openrtm-aist-1.1.2+20160604+1730+12~ubuntu12.04.1/examples/Composite'
/bin/bash ../../libtool --tag=CXX   --mode=compile i686-linux-gnu-g++ -DHAVE_CONFIG_H -I. -I../../src/lib/rtm  -I../../src/lib -I../../src/lib/coil/include -I../../src/lib/rtm/idl -Wall -fPIC -O2  -Wall -fPIC -O2 -MT Controller.lo -MD -MP -MF .deps/Controller.Tpo -c -o Controller.lo Controller.cpp
libtool: compile:  i686-linux-gnu-g++ -DHAVE_CONFIG_H -I. -I../../src/lib/rtm -I../../src/lib -I../../src/lib/coil/include -I../../src/lib/rtm/idl -Wall -fPIC -O2 -Wall -fPIC -O2 -MT Controller.lo -MD -MP -MF .deps/Controller.Tpo -c Controller.cpp  -fPIC -DPIC -o .libs/Controller.o
In file included from ../../src/lib/rtm/PortBase.h:31:0,
                 from ../../src/lib/rtm/RTObject.h:27,
                 from ../../src/lib/rtm/DataFlowComponentBase.h:24,
                 from Controller.h:12,
                 from Controller.cpp:7:
../../src/lib/rtm/NVUtil.h: In function 'SDOPackage::NameValue NVUtil::newNV(const char*, Value) [with Value = int]':
../../src/lib/rtm/PortBase.h:1878:7:   instantiated from 'void RTC::PortBase::addProperty(const char*, ValueType) [with ValueType = int]'
../../src/lib/rtm/OutPort.h:141:7:   instantiated from 'RTC::OutPort<DataType>::OutPort(const char*, DataType&) [with DataType = RTC::TimedFloat]'
Controller.cpp:33:26:   instantiated from here
../../src/lib/rtm/NVUtil.h:83:5: error: ambiguous overload for 'operator<<=' in 'nv.SDOPackage::NameValue::value <<= value'
../../src/lib/rtm/NVUtil.h:83:5: note: candidates are:
/usr/include/omniORB4/CORBA_Any.h:85:8: note: void CORBA::Any::operator<<=(CORBA::Short)
/usr/include/omniORB4/CORBA_Any.h:86:8: note: void CORBA::Any::operator<<=(CORBA::UShort)
/usr/include/omniORB4/CORBA_Any.h:87:8: note: void CORBA::Any::operator<<=(CORBA::Long)
/usr/include/omniORB4/CORBA_Any.h:88:8: note: void CORBA::Any::operator<<=(CORBA::ULong)
/usr/include/omniORB4/CORBA_Any.h:90:8: note: void CORBA::Any::operator<<=(CORBA::LongLong)
/usr/include/omniORB4/CORBA_Any.h:91:8: note: void CORBA::Any::operator<<=(CORBA::ULongLong)
fkanehiro commented 8 years ago

上のコンパイルエラーですが32bitだけで起きるようです。

fkanehiro commented 8 years ago

@n-ando さん、五月雨式で申し訳ありませんが、

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffa08aa700 (LWP 5106)]
__memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
33  ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: そのようなファイルやディレクトリはありません.
(gdb) bt
#0  __memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
#1  0x00007fffc386fe48 in cdrMemoryStream::put_octet_array(unsigned char const*, int, omni::alignment_t) () from /usr/lib/libomniORB4.so.1
#2  0x00007fffc5b40246 in Img::CameraImage::operator>>= (this=0x7fff84003878, 
    _n=...)
    at /home/kanehiro/src/choreonoid/src/OpenRTMPlugin/corba/CameraImageSk.cpp:70
#3  0x00007fffc5b403db in Img::TimedCameraImage::operator>>= (
    this=0x7fff84003870, _n=...)
    at /home/kanehiro/src/choreonoid/src/OpenRTMPlugin/corba/CameraImageSk.cpp:103
#4  0x00007fffc31e5152 in CORBA::Any::operator=(CORBA::Any const&) ()
   from /usr/lib/libomniDynamic4.so.1
#5  0x00007fffc2d2ca45 in RTC::PortBase::get_port_profile() ()
   from /usr/lib/x86_64-linux-gnu/libRTC-1.1.2.so

といったエラーも起きます。 カメラ画像の入った(入る予定?)のポートのプロファイルを取ろうとして落ちるようです。 https://github.com/s-nakaoka/choreonoid/blob/master/src/OpenRTMPlugin/corba/CameraImage.idl

fkanehiro commented 8 years ago

m_profileに排他制御しないといけないということでしょうか。 試してみます。

n-ando commented 8 years ago

おそらくそうですね。>排他制御

n-ando commented 8 years ago

こうですかね?>排他制御

Index: OutPort.h
===================================================================
--- OutPort.h   (リビジョン 2750)
+++ OutPort.h   (作業コピー)
@@ -139,7 +139,10 @@
         m_value(value), m_onWrite(0), m_onWriteConvert(0)
     {
       addProperty("dataport.data_value", (CORBA::Short)0);
-      m_propValueIndex = NVUtil::find_index(m_profile.properties, "dataport.data_value");
+      {
+       Guard guard(m_profile_mutex);
+       m_propValueIndex = NVUtil::find_index(m_profile.properties, "dataport.data_value");
+      }
     }

     /*!
@@ -211,7 +214,10 @@
           (*m_onWrite)(value);
           RTC_TRACE(("OnWrite called"));
         }
-      m_profile.properties[m_propValueIndex].value <<= value;
+      {
+       Guard guard(m_profile_mutex);
+       m_profile.properties[m_propValueIndex].value <<= value;
+      }

       bool result(true);
       std::vector<const char *> disconnect_ids;
fkanehiro commented 8 years ago

はい、それで良さそうです。 svnへの反映をお願いします。

fkanehiro commented 8 years ago

@n-ando さん、排他制御の修正がtrunkにしか入っていないようなので、RELENG_1_1にも反映して頂けませんか?

n-ando commented 8 years ago

すみません、ROBOMECH参加中で作業が遅れました。現在RELENG_1_1にも修正がコミットされております。