5.20. Memory Leaks/Growth

5.20.1. [Critical] Memory leak in best-effort writers when switching from more than one unicast locator to a multicast locator

Each time a best-effort DataWriter transitioned from using more than one unicast locator to using a multicast locator, a small amount of memory leaked. Such a transition is beyond the scope of regular system operations and can only arise through the manipulation of Data(p) RTPS messages. Such manipulation might stem from internal testing scenarios or unauthorized access by a malicious entity in systems where DDS security measures have not been fully implemented or enforced.

[RTI Issue ID CORE-14427]

5.20.2. [Critical] Concurrency problem in Asynchronous WaitSet’s global instance initialization led to memory and TSS key leaks in multi-threading scenarios

The first time an Asynchronous WaitSet is created, Connext initializes a global singleton instance shared among all the Asynchronous WaitSets in your application. That global instance contains some fields used in the Asynchronous WaitSet logic, like a thread-specific storage (TSS) key.

Due to a concurrency problem, several threads could initialize that global singleton instance at the same time, without realizing that the instance was already initialized. Some existing pointers were overwritten with new ones, resulting in a leak of the TSS key and a memory leak similar to the following:

==44591== 32 bytes in 1 blocks are definitely lost in loss record 1 of 1
==44591==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==44591==    by 0x49789AD: RTIOsapiHeap_reallocateMemoryInternal (heap.c:830)
==44591==    by 0x4A8DF06: REDAWorkerPerThread_newWithTss (Worker.c:1599)
==44591==    by 0x99D63F: DDS_AsyncWaitSetGlobals_initializeConcurrency (AsyncWaitSetGlobals.c:247)
==44591==    by 0x99DB9E: DDS_AsyncWaitSetGlobals_get_instance (AsyncWaitSetGlobals.c:351)
...

This issue could happen if your application had several threads creating Asynchronous WaitSets (or calling DDS_DomainParticipantFactory_unregister_thread) simultaneously and for the first time.

If this process was repeated enough times in a loop after calling DDS_DomainParticipantFactory_finalize_instance (that deletes the global singleton instance), theoretically, this concurrency problem could lead to an unbounded memory growth or to reaching the maximum limit of TSS keys available in your operating system (the consequences of reaching that limit are explained in CORE-14157). In practice, the timing for this race condition to happen was highly unlikely.

The concurrency issue is now fixed and the threads do nothing if the global singleton instance is already initialized.

[RTI Issue ID CORE-14321]

5.20.3. [Critical] Memory leak when creating a QueryCondition with Parameters

When creating a new QueryCondition with Parameters using the create_querycondition_w_params API, some memory was leaked.

[RTI Issue ID CORE-14301]

5.20.4. [Critical] Memory leak when using NetworkCaptureParams

When using the Java API, some native memory could be leaked when starting Network Capture with non-default parameters or when setting new default parameters. This leak was restricted to using parameters, and did not affect Network Capture execution itself.

[RTI Issue ID CORE-14275]

5.20.5. [Critical] Memory Leak in Java API when printing QoS objects

When using the Java API, printing QoS objects could have caused some native memory to be leaked. This issue affected any QoS field of variable-length, such as Entity Name; therefore, it affected the following:

  • DomainParticipantQos

  • PublisherQos

  • SubscriberQos

  • DataWriterQos

  • DataReaderQos

[RTI Issue ID CORE-14252]

5.20.6. [Critical] Asynchronous WaitSet global instance’s thread-specific storage key leaked

The first time an Asynchronous WaitSet is created, Connext initializes a global singleton instance shared among all the Asynchronous WaitSets in your application. That global instance contains some fields used in the Asynchronous WaitSet logic, like a thread-specific storage (TSS) key.

The Asynchronous WaitSet global instance is deleted when calling DDS_DomainParticipantFactory_finalize_instance. However, the TSS key was never deleted, resulting in a leak of the key.

If, for some reason, your application created AsyncWaitSets and finalized the DomainParticipantFactory instance enough times in a loop, you could eventually reach the limit of available TSS keys imposed by your operating system. Once that limit was reached, next attempts of Connext to create a TSS key resulted in failure:

ERROR DDS_AsyncWaitSetGlobals_initializeConcurrency:ERROR: Failed to create thread-specific storage for WSCT
ERROR DDS_AsyncWaitSetGlobals_get_instance:!init concurrency
ERROR DDS_AsyncWaitSet_newI:!init DDS_AsyncWaitSet

Not only AsyncWaitSets use TSS keys in Connext. If your system ran out of keys because of this leak, the issue could affect any other Connext feature relying on thread-specific storage.

The TSS key is now always deleted when calling DDS_DomainParticipantFactory_finalize_instance.

Note: Even if your application doesn’t use Asynchronous WaitSets, you could have been affected by this issue if you called DDS_DomainParticipantFactory_unregister_thread. This function also initializes the global singleton if it is not already initialized.

[RTI Issue ID CORE-14157]

5.20.7. [Major] Memory leak when using XML-Based Application Creation and DynamicData

When using XML-Based Application Creation and DynamicData, a small amount of memory was leaked for every DynamicData type registered in a DomainParticipant, upon DomainParticipant deletion.

[RTI Issue ID CORE-14163]

5.20.8. [Minor] Memory leak when finalizing DomainParticipantFactory for first time

When finalizing the DomainParticipantFactory for the first time, and only for the first time, some native memory was never being freed. The leak could be observed when using HeapMonitoring.take_heap_snapshot. For example:

block_id, timestamp, block_size, alloc_method_name, type_name, pool_alloc, pool_buffer_size, pool_buffer_count, topic_name, function_name, activity_context
359, 1702981391, 48, RTIOsapiHeap_allocateStructure, struct REDAObjectPerWorker, MALLOC, 0, 0, unknown, unknown, unknown

[RTI Issue ID CORE-14180]

5.20.9. [Minor] DomainParticipantFactory was leaked when factory finalization failed

When an error occurred during the finalization of the DomainParticipantFactory (for example, because some DomainParticipants were not deleted), the DomainParticipantFactory itself would have been leaked.

[RTI Issue ID CORE-14302]

5.20.10. [Minor] Potential Memory leak upon ContentFilteredTopic creation failure

When creating a ContentFilteredTopic with a custom filter, a native memory leak could occur if the compile function of the filter failed with a Java exception.

[RTI Issue ID CORE-14333]

5.20.11. [Critical] ODBC DataWriters may have leaked instances when they were replaced if writer-side filtering was used

DataWriters configured to use an ODBC database may have leaked instances when they were replaced. The instances were leaked if writer-side filtering was used, and a sample for that instance was filtered on the writer-side.

[RTI Issue ID CORE-14434]