Describe the bug
PeriodicExecutionContextに複数のRTCをadd_componentした状態でRTCをshutdownすると解放済みメモリにアクセスしてしまいます。
To Reproduce
OpenRTM1.1.2を使用
- Managerに2つのRTCをcreate_componentする. (それぞれにPeriodicExecutionContextがattachされる)
- 2つめのRTCのPeriodicExecutionContextに、1つめのRTCをadd_componentする
- 2つめのRTCをshutdown()する
- 1つめのRTCをshutdown()する
- 解放済みメモリへのアクセスによるエラーが発生する
Reproducibility
毎回
Environment
- OS: Ubuntu 18.04
- OpenRTM-aist Version 1.1.2
- ROS: melodic
Additional context
リンク先のように変更すると直りました。
tork-a/openrtm_aist-release@5148d55
上の手順の2で1つめのRTCのメンバのm_ecOtherに2つめのRTCのPeriodicExecutionContextへのポインタが入り、
|
UniqueId RTObject_impl::attach_context(ExecutionContext_ptr exec_context) |
|
throw (CORBA::SystemException) |
|
{ |
|
RTC_TRACE(("attach_context()")); |
|
// ID: 0 - (offset-1) : owned ec |
|
// ID: offset - : participating ec |
|
// owned ec index = ID |
|
// participate ec index = ID - offset |
|
ExecutionContextService_var ecs; |
|
ecs = ExecutionContextService::_narrow(exec_context); |
|
if (CORBA::is_nil(ecs)) |
|
{ |
|
return -1; |
|
} |
|
|
|
// if m_ecOther has nil element, insert attached ec to there. |
|
for (::CORBA::ULong i(0), len(m_ecOther.length()); i < len; ++i) |
|
{ |
|
if (::CORBA::is_nil(m_ecOther[i])) |
|
{ |
|
m_ecOther[i] = ExecutionContextService::_duplicate(ecs); |
|
UniqueId ec_id(i + ECOTHER_OFFSET); |
|
onAttachExecutionContext(ec_id); |
|
return ec_id; |
|
} |
|
} |
|
|
|
// no space in the list, push back ec to the last. |
|
CORBA_SeqUtil:: |
|
push_back(m_ecOther, ExecutionContextService::_duplicate(ecs)); |
|
|
|
UniqueId ec_id((m_ecOther.length() - 1) + ECOTHER_OFFSET); |
|
onAttachExecutionContext(ec_id); |
|
return ec_id; |
|
} |
手順の3で2つめのRTCのPeriodicExecutionContextがdeleteされ、
|
void RTObject_impl::finalizeContexts() |
|
{ |
|
RTC_TRACE(("finalizeContexts()")); |
|
for (int i(0), len(m_eclist.size()); i < len; ++i) |
|
{ |
|
m_eclist[i]->stop(); |
|
try |
|
{ |
|
PortableServer::ObjectId_var oid |
|
= m_pPOA->servant_to_id(m_eclist[i]); |
|
m_pPOA->deactivate_object(oid); |
|
} |
|
catch (PortableServer::POA::ServantNotActive &e) |
|
{ |
|
RTC_ERROR(("%s", e._name())); |
|
} |
|
catch (PortableServer::POA::WrongPolicy &e) |
|
{ |
|
RTC_ERROR(("%s", e._name())); |
|
} |
|
catch (...) |
|
{ |
|
// never throws exception |
|
RTC_ERROR(("Unknown exception caught.")); |
|
} |
|
delete m_eclist[i]; |
|
} |
|
if (!m_eclist.empty()) |
|
{ |
|
m_eclist.clear(); |
|
} |
|
} |
手順の4で1つめのRTCのメンバのm_ecOtherにアクセスする
|
CORBA_SeqUtil::for_each(m_ecOther, |
|
deactivate_comps(m_objref)); |
|
|
|
// owned EC will be finalised later in finalizeContext(). |
|
|
|
// detach myself from other EC |
|
for (CORBA::ULong ic(0), len(m_ecOther.length()); ic < len; ++ic) |
|
{ |
|
// m_ecOther[ic]->stop(); |
|
RTC::LightweightRTObject_var comp(this->_this()); |
|
if (! ::CORBA::is_nil(m_ecOther[ic])) |
|
{ |
|
m_ecOther[ic]->remove_component(comp.in()); |
|
} |
ことで、解放済みメモリへのアクセスが発生しているようです。
hrpsysでこの現象に遭遇しました。最新版のOpenRTM-aistでは、このあたりの処理が大きく変わっているため、同じ現象が発生しないかもしれません。
Describe the bug
PeriodicExecutionContextに複数のRTCをadd_componentした状態でRTCをshutdownすると解放済みメモリにアクセスしてしまいます。
To Reproduce
OpenRTM1.1.2を使用
Reproducibility
毎回
Environment
Additional context
リンク先のように変更すると直りました。
tork-a/openrtm_aist-release@5148d55
上の手順の2で1つめのRTCのメンバのm_ecOtherに2つめのRTCのPeriodicExecutionContextへのポインタが入り、
OpenRTM-aist/src/lib/rtm/RTObject.cpp
Lines 587 to 621 in 22628ce
手順の3で2つめのRTCのPeriodicExecutionContextがdeleteされ、
OpenRTM-aist/src/lib/rtm/RTObject.cpp
Lines 2109 to 2140 in 22628ce
手順の4で1つめのRTCのメンバのm_ecOtherにアクセスする
OpenRTM-aist/src/lib/rtm/RTObject.cpp
Lines 409 to 422 in 22628ce
ことで、解放済みメモリへのアクセスが発生しているようです。
hrpsysでこの現象に遭遇しました。最新版のOpenRTM-aistでは、このあたりの処理が大きく変わっているため、同じ現象が発生しないかもしれません。