/* src/ddscxx/src/org/eclipse/cyclonedds/core/EntityDelegate.cpp : 226 */
org::eclipse::cyclonedds::core::EntityDelegate::listener_set(void *_listener,
const dds::core::status::StatusMask& mask,
bool reset_on_invoke) { // This index with (4)
....
if (this->enabled_) // This index with (5)
{
dds_return_t ret;
ret = dds_set_listener(this->ddsc_entity, callbacks);
ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Setting listener failed.");
}
// Delete previous ddsc listener callbacks object
if (this->listener_callbacks != NULL)
{
void *prev_arg;
dds_lget_data_available_arg(this->listener_callbacks, nullptr, &prev_arg, nullptr);
dds_delete_listener(this->listener_callbacks);
delete reinterpret_cast<org::eclipse::cyclonedds::core::ListenerArg *>(prev_arg); //This index with (6)
}
...
I. When call function (1), it will call (2) before (1).
II. When call (1), it will call (3) to set a default dds_listener_t to dds_entity_t.
III. After this, the real listener will be generate in (4).
IV. But at (5), this->enabled_ is false, so it will not set real listener to dds_entity_t.
V. Then, current dds_listener_t which binding on dds_entity_t will be delete by (6).
VI. After all of above, (1) will call enable() to set real listener to dds_entity_t.
So when an event comes between V and VI, it will crashed reason of (6), arg is released.
Solution
I. Make this->listener_callbacks to nullptr.
II. After (3), set this->enable_ = true
I don't know why there is a this->listener_callbacks, so I dont know how to repair it will make a lowest effect.
Problem descriptor
I found a random crash when create a DataWriter or a DataReader, it crush in:
Minimal Reproducible Example:
Problem location
I found the problem occurs here(eg. with DataWriter, also in DataReader):
I. When call function
(1)
, it will call(2)
before(1)
. II. When call(1)
, it will call(3)
to set a defaultdds_listener_t
todds_entity_t
. III. After this, the real listener will be generate in (4). IV. But at (5),this->enabled_
is false, so it will not set real listener todds_entity_t
. V. Then, currentdds_listener_t
which binding ondds_entity_t
will be delete by (6). VI. After all of above, (1) will callenable()
to set real listener todds_entity_t
.So when an event comes between V and VI, it will crashed reason of (6), arg is released.
Solution
I. Make
this->listener_callbacks
to nullptr. II. After (3), setthis->enable_ = true
I don't know why there is a
this->listener_callbacks
, so I dont know how to repair it will make a lowest effect.