Crash after calling key_value() in modern C++

11 posts / 0 new
Last post
Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6
Crash after calling key_value() in modern C++

I am updating an existing application to use modern C++. However, after calling key_value() on a reader, the application crashes. It looks like it is crashing while attempting to delete a string contained in the data type. 

Code similiar to what I'm using is below. The debugger indicates the crash occurs at: rti::core::memory::OsapiAllocator<char>::release(void * object) Line 63 C++ .

Am I making this call correctly? Is there something I'm missing? Any help would be appreciated.

 

Thanks

 

dds::sub::LoanedSamples<T> samples = reader.take();

for( const auto& r : samples )
{
  dds::sub::SampleInfo info = r->info();
  dds::sub::status::InstanceState instanceState = info.state().instance_state();
  if( info.valid() )
  {
    if( instanceState == dds::sub::status::InstanceState::alive() )
    {  //Do things
    }

  } else {

    if( instanceState == dds::sub::status::InstanceState::not_alive_no_writers()
      || instanceState == dds::sub::status::InstanceState::not_alive_disposed() )
    {
      T v;
      reader.key_value( v, info.instance_handle() );
      // Do things
    }  //Crashes here
  }
}

 

 

Offline
Last seen: 6 months 4 weeks ago
Joined: 01/10/2013
Posts: 28

Hi, 

You're using the API correctly, this is a known issue that we came across last week. Can you add:

dds::topic::topic_type_support<T>::initialize_sample(v);

before calling key_value? The problem occurs when calling that API with a default-constructed sample. I'm assuming that your type has a string member as the key? 

 

 

Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6

That has solved the issue. Yes, I'm using a key that contains a string.

Thanks for the quick response!

Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6

I spoke too soon. I am still having an issue with this piece of code, even after adding the initialize_sample() call.

if( instanceState == dds::sub::status::InstanceState::not_alive_no_writers()

  || instanceState == dds::sub::status::InstanceState::not_alive_disposed() )

  {

    T z;

    dds::topic::topic_type_support::initialize_sample( z );

    reader.key_value( z, info.instance_handle() );

 

Now, periodically, (and quite reliably when I kill the writer application) I get a warning from the debugger that reads, "Run-Time Check Failure #2 - Stack around the variable 'z' was corrupted.". Is this a related bug? Is there a similar work around?

Offline
Last seen: 6 months 4 weeks ago
Joined: 01/10/2013
Posts: 28

Hi, 

I haven't been able to reproduce this, however, it looks related to the same bug.  Do you think you could share your type with me? And maybe a representative set of samples that you would send? If you can share your publisher and subscriber code that would be helpful too. 

Thanks!

Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6

My type is as follows:

module TypeDefs{
typedef string<16> Id_Type;

struct Key_Type
{
  unsigned long Obj_Id;
  Id_Type Own_Id;
}; //@top-level false

enum TQC
{
  A = 0,
  B = 1,
  C = 2,
  D = 3,
  E = 4,
  F = 5,
  G = 6,
  H = 7,
  I = 8,
  J = 9,
  K = 10,
  L = 11,
  M = 12,
  N = 13,
  O = 14,
  P = 15
};

struct Time_Type
{
  long long Seconds;
  long Nano_Seconds;
}; //@top-level false
}

module TD{
struct TQD_Record
{
  TypeDefs::Key_Type Object_Key; //@key
  TypeDefs::TQC TQ;
  TypeDefs::Time_Type Time;
};
}

 

I set up my reader, as follows:

dds::core::QosProvider::Default()->default_library( DDS_QOS_LIBRARY_NAME);
dds::core::QosProvider::Default()->default_profile( DDS_QOS_PROFILE_NAME );

dds::domain::DomainParticipant p = dds::domain::find( domainID );

if( p == dds::core::null )
  p = dds::domain::DomainParticipant( domainID );

dds::topic::Topic<TD::TQD_Record> topic = dds::topic::find<dds::topic::Topic<TD::TQD_Record>>( p, topicName );

if( topic == dds::core::null )
  topic = dds::topic::Topic<TD::TQD_Record>( p, topicName );
return dds::pub::DataWriter<TD::TQD_Record>( dds::pub::Publisher( p ), topic, dds::core::QosProvider::Default()->datawriter_qos_w_topic_name( topicName ) );

 

And my writer:

dds::pub::DataWriter<TD::TQD_Record> trackQualityDataWriter(
  dds::pub::Publisher( participant ),
  dds::topic::Topic<TD::TQD_Record>( participant, topicName ),
  dds::core::QosProvider::Default()->datawriter_qos_w_topic_name( topicName ) );

 

I've cut the code from a much large application, so please excuse any typos.

Thank you.

Offline
Last seen: 6 months 4 weeks ago
Joined: 01/10/2013
Posts: 28

Hi again, 

Thank you for the information, I still haven't been able to reproduce this crash, can I get some more information from you? What QoS values are you using for the reader and the writer? Is there a small set of sample and/or key values that will reproduce the crash? What version of Visual Studio are you using? 32 or 64-bit?  What command line arguments did you use with rtiddsgen to generate the type code? 

What I have tried to do is to write 10 instances of your type, with various string lengths for the Own_Id field, and then I have the same code as you have pasted above in my on_data_available callback. I have tried to kill the writer application both gracefully and ungracefully. Do you see something that I am doing differently than you? Or see something else that I could try?

 

Thank you

Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6

My QoS profile is defined as: 

<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:\Program Files (x86)\RTI\ndds.5.1.0\resource\qos_profiles_5.1.0\schema\rti_dds_profiles.xsd"
version="5.1.0">
<qos_library name="External_Qos_Library">

<qos_profile name="Data_Profile" is_default_qos="false">
<datawriter_qos>
<reliability>
<kind>DDS_RELIABLE_RELIABILITY_QOS</kind>
</reliability>
<history>
<kind>DDS_KEEP_LAST_HISTORY_QOS</kind>
<depth>10</depth>
</history>
<durability>
<kind>DDS_TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>
<liveliness>
<kind>DDS_AUTOMATIC_LIVELINESS_QOS</kind>
<lease_duration>
<sec>1</sec>
<nanosec>0</nanosec>
</lease_duration>
</liveliness>
</datawriter_qos>
<datareader_qos>
<reliability>
<kind>DDS_RELIABLE_RELIABILITY_QOS</kind>
</reliability>
<history>
<kind>DDS_KEEP_LAST_HISTORY_QOS</kind>
<depth>10</depth>
</history>
<durability>
<kind>DDS_TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>
<liveliness>
<kind>DDS_AUTOMATIC_LIVELINESS_QOS</kind>
<lease_duration>
<sec>1</sec>
<nanosec>0</nanosec>
</lease_duration>
</liveliness>
</datareader_qos>
</qos_profile>
</qos_library>

<!-- Qos Library -->
<qos_library name="MyLibrary">

<qos_profile name="MyProfile" >

<datareader_qos topic_filter="TDQ_Topic" base_name="External_Qos_Library::Data_Profile" />
<datawriter_qos topic_filter="TDQ_Topic" base_name="External_Qos_Library::Data_Profile" />

</qos_profile>
</qos_library>
</dds>

In my application I am sending five TQD_Record samples, one after another, every second. The sample contains: Object_Key{<256-270>, "XYZ"}, TQ{F}, Time{0, 0}. (<256-270> is the range of values sent each second. One sample for each value is sent each second.) The application runs indefinitely. The debugger sometimes reports the warning several times in a row, sometimes it may run for a period of time upto an hour without reporting it, usually it will take just a few minutes. The warning has an option to continue. Clicking it allows the application to continue running.

I am using VS2013 and compiling 32 bit applications. 

The command I'm using to generate my type code is: rtiddsgen.bat" -ppPath "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\cl.exe" -language C++11 -update typefiles -inputIdl $idlName -ppOption /nologo -ppOption /C -ppOption /E -ppOption /X -I .

In addition to this data type and topic, there are about 20 other types being used and sent in the application. (Each datatype has its own topic in the application.) Most of them have been created in a similar manner, and several of them use the same QoS. However, the reported warning is only ever seen with this topic and datatype. 

 

 

Offline
Last seen: 6 months 4 weeks ago
Joined: 01/10/2013
Posts: 28

Hi, 

I just wanted to let you know I'm still working on reproducing the issue. I still haven't seen the warning, but I'll look through the code this afternoon regardless of whether I reproduce it to see if I can identify where this might be happening. Thanks for all of the information. I'll keep you posted. 

Offline
Last seen: 6 months 4 weeks ago
Joined: 01/10/2013
Posts: 28

I still haven't been able to reproduce the stack corruption warning, so I was wondering if you had tried to reproduce this problem with a simple hello world application? Do you think you could generate a Hello World example using -example option in rtiddsgen and reprouce the issue and send that to me?

Thanks!

Offline
Last seen: 8 years 1 month ago
Joined: 08/06/2015
Posts: 6

Thanks for your effort. 

I haven't been able to reproduce the issue in a "Hello World" sized application. Perhaps it's an issue in using this data type with other data types and topics? Everything runs correctly if I leave that datatype out of the reading. 

I will try to trim down our application into something I can easily send you. But that could take some time. 

I should have mentioned before, the reading in this application is done by polling the DataReaders at about 5Hz. I don't know if that mechanism would be any different than handling the on_data_available() callback. 

 

 

Thanks.