Skip to content

[#24620] Fixed segfault in 'RepeaterDataFilter.cpp' when forwarding dispose/unregister samples with a null check#186

Merged
Danipiza merged 3 commits into
mainfrom
fix/dispose
Jun 18, 2026
Merged

[#24620] Fixed segfault in 'RepeaterDataFilter.cpp' when forwarding dispose/unregister samples with a null check#186
Danipiza merged 3 commits into
mainfrom
fix/dispose

Conversation

@Danipiza

@Danipiza Danipiza commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description

A repeater participant of the DDS (xml) kind crashes with a SIGSEGV when it forwards a NOT_ALIVE_DISPOSED /
NOT_ALIVE_UNREGISTERED sample on a topic that has matched readers.

dds::RepeaterDataFilter::evaluate reads the message origin from sample_info.user_write_data and dereferences it
unconditionally:

auto write_data = std::static_pointer_cast(sample_info.user_write_data);
bool is_relevant = write_data->last_writer_guid_prefix != reader_guid.guidPrefix; // <-- null deref

Solution

Guard against a null write_data in dds::RepeaterDataFilter::evaluate. When the origin information is absent
(dispose/unregister), the sample's origin participant is unknown, so it cannot be filtered out by origin; it is
considered relevant and let through

Test

It can be tested with ShapesDemo in 3 terminals. Or the DDS-Router regression tests

ShapesDemo (3 terminals)

ShapesDemo # publisher domain 39
ShapesDemo # subscriber domain 40
ddsrouter -c repro_repeater.yaml

repro_repeater.yaml

xml:
  raw: |
    <?xml version="1.0" encoding="UTF-8" ?>
    <profiles xmlns="http://www.eprosima.com">
        <participant profile_name="part_domain_39">
            <domainId>39</domainId>
            <rtps></rtps>
        </participant>
        <participant profile_name="part_domain_40">
            <domainId>40</domainId>
            <rtps></rtps>
        </participant>
    </profiles>

allowlist:
  - name: "Square"          # ShapesDemo "Square" topic (type ShapeType, keyed on color)

participants:

  - name: xml_39
    kind: xml
    profile: part_domain_39
    repeater: true          # <-- makes its writers use dds::RepeaterDataFilter

  - name: xml_40
    kind: xml
    profile: part_domain_40
    repeater: true          # <-- makes its writers use dds::RepeaterDataFilter

DDS-Router

colcon build --packages-select ddspipe_participants ddsrouter_core --cmake-args -DBUILD_TESTS=ON --allow-overriding ddspipe_participants ddsrouter_core
colcon test --packages-select ddsrouter_core --ctest-args -R DDSTestRepeaterDisposeKey --event-handlers console_direct+

Error

$ gdb -q -ex run --args     /home/danny/eProsima/DDS-Pipe/install/ddsrouter_tool/bin/ddsrouter     -c /home/danny/eProsima/DDS-Pipe/repro_repeater.yaml
Reading symbols from /home/danny/eProsima/DDS-Pipe/install/ddsrouter_tool/bin/ddsrouter...
Starting program: /home/danny/eProsima/DDS-Pipe/install/ddsrouter_tool/bin/ddsrouter -c /home/danny/eProsima/DDS-Pipe/repro_repeater.yaml

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Downloading separate debug info for system-supplied DSO at 0x7ffff7fc3000
Downloading separate debug info for /lib/x86_64-linux-gnu/libstdc++.so.6                            
Downloading separate debug info for /lib/x86_64-linux-gnu/libgcc_s.so.1                             
[Thread debugging using libthread_db enabled]                                                       
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Downloading separate debug info for /lib/x86_64-linux-gnu/libssl.so.3
Downloading separate debug info for /lib/x86_64-linux-gnu/libcrypto.so.3                            
Starting DDS Router Tool execution.                                                                 
[New Thread 0x7ffff45ff6c0 (LWP 84621)]
[New Thread 0x7ffff3dfe6c0 (LWP 84622)]
[New Thread 0x7ffff35fd6c0 (LWP 84623)]
License valid for holder: ACME inc. [Currently execution maximum running time: 10 minutes]
[New Thread 0x7ffff2dfc6c0 (LWP 84624)]
[New Thread 0x7ffff25fb6c0 (LWP 84625)]
[New Thread 0x7ffff1dfa6c0 (LWP 84626)]
[New Thread 0x7ffff15f96c0 (LWP 84627)]
[New Thread 0x7ffff0df86c0 (LWP 84628)]
[New Thread 0x7ffff05f76c0 (LWP 84629)]
[New Thread 0x7fffefdf66c0 (LWP 84630)]
[New Thread 0x7fffef5f56c0 (LWP 84631)]
[New Thread 0x7fffeedf46c0 (LWP 84632)]
[New Thread 0x7fffee5f36c0 (LWP 84633)]
[New Thread 0x7fffeddf26c0 (LWP 84634)]
[New Thread 0x7fffed56a6c0 (LWP 84635)]
[New Thread 0x7fffecd696c0 (LWP 84636)]
[New Thread 0x7fffe7fff6c0 (LWP 84637)]
[New Thread 0x7fffe77fe6c0 (LWP 84638)]
[New Thread 0x7fffe6ffd6c0 (LWP 84639)]
[New Thread 0x7fffe67fc6c0 (LWP 84640)]
[New Thread 0x7fffe5ffb6c0 (LWP 84641)]
[New Thread 0x7fffe57fa6c0 (LWP 84642)]
[New Thread 0x7fffe4ff96c0 (LWP 84643)]
[New Thread 0x7fffdbfff6c0 (LWP 84644)]
[New Thread 0x7fffdb7fe6c0 (LWP 84645)]
[New Thread 0x7fffdaffd6c0 (LWP 84646)]
[New Thread 0x7fffda7fc6c0 (LWP 84647)]
[New Thread 0x7fffd9ffb6c0 (LWP 84648)]
[New Thread 0x7fffd97fa6c0 (LWP 84649)]
[New Thread 0x7fffd8ff96c0 (LWP 84650)]
[New Thread 0x7fffd3fff6c0 (LWP 84651)]
[New Thread 0x7fffd37fe6c0 (LWP 84652)]
[New Thread 0x7fffd2ffd6c0 (LWP 84653)]
[New Thread 0x7fffd27fc6c0 (LWP 84654)]
[New Thread 0x7fffd1ffb6c0 (LWP 84655)]
[New Thread 0x7fffd17fa6c0 (LWP 84656)]
[New Thread 0x7fffd0ff96c0 (LWP 84657)]
[New Thread 0x7fffd07f86c0 (LWP 84658)]
DDS Router running.

Thread 29 "ddsrouter" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd9ffb6c0 (LWP 84648)]
Download failed: Invalid argument.  Continuing without source file ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S.
__memcmp_avx2_movbe () at ../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:415
warning: 415	../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S: No such file or directory
(gdb) bt
#0  __memcmp_avx2_movbe () at ../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:415
#1  0x00007ffff7b80229 in std::__memcmp<unsigned int, unsigned int> (__first1=0x8, 
    __first2=0x7fffa8024b58, __num=3) at /usr/include/c++/13/bits/stl_algobase.h:108
#2  0x00007ffff7b7f76d in std::__equal<true>::equal<unsigned int> (__first1=0x8, __last1=0x14, 
    __first2=0x7fffa8024b58) at /usr/include/c++/13/bits/stl_algobase.h:1185
#3  0x00007ffff7b7ebab in std::__equal_aux1<unsigned int const*, unsigned int const*> (
    __first1=0x8, __last1=0x14, __first2=0x7fffa8024b58)
    at /usr/include/c++/13/bits/stl_algobase.h:1219
#4  0x00007ffff7b7da0f in std::__equal_aux<unsigned int const*, unsigned int const*> (
    __first1=0x8, __last1=0x14, __first2=0x7fffa8024b58)
    at /usr/include/c++/13/bits/stl_algobase.h:1227
#5  0x00007ffff7b7be2f in std::equal<unsigned int const*, unsigned int const*> (__first1=0x8, 
    __last1=0x14, __first2=0x7fffa8024b58) at /usr/include/c++/13/bits/stl_algobase.h:1557
#6  0x00007ffff7b795ec in std::operator==<unsigned int, 3ul> (__one=..., __two=...)
    at /usr/include/c++/13/array:298
#7  0x00007ffff7b766d3 in eprosima::fastdds::rtps::GuidPrefix_t::operator== (this=0x8, prefix=...)
    at /home/danny/eProsima/DDS-Pipe/install/fastdds/include/fastdds/rtps/common/GuidPrefix_t.hpp:115
#8  0x00007ffff7b9d711 in eprosima::fastdds::rtps::GuidPrefix_t::operator!= (this=0x8, prefix=...)
    at /home/danny/eProsima/DDS-Pipe/install/fastdds/include/fastdds/rtps/common/GuidPrefix_t.hpp:126
#9  0x00007ffff7c09da1 in eprosima::ddspipe::participants::dds::RepeaterDataFilter::evaluate (
    this=0x7fffa8024ab0, payload=..., sample_info=..., reader_guid=...)
    at /home/danny/eProsima/DDS-Pipe/src/ddspipe/ddspipe_participants/src/cpp/writer/dds/filter/RepeaterDataFilter.cpp:56
#10 0x00007ffff6573b7e in eprosima::fastdds::dds::DataWriterImpl::is_relevant (
    this=0x7fffa8019310, change=..., reader_guid=...)
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/fastdds/publisher/DataWriterImpl.cpp:2552
#11 0x00007ffff6ca6ed1 in eprosima::fastdds::rtps::StatelessWriter::deliver_sample_nts (
    this=0x7fffa8024160, cache_change=0x7fffa8023b10, group=..., locator_selector=...)
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/rtps/writer/StatelessWriter.cpp:839
#12 0x00007ffff6b07c0e in eprosima::fastdds::rtps::FlowControllerImpl<eprosima::fastdds::rtps::FlowControllerPureSyncPublishMode, eprosima::fastdds::rtps::FlowControllerFifoSchedule>::add_new_sample_impl<eprosima::fastdds::rtps::FlowControllerPureSyncPublishMode> (this=0x5555557b1860, 
    writer=0x7fffa8024160, change=0x7fffa8023b10, 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 106179564232877ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp:1265
#13 0x00007ffff6b0481a in eprosima::fastdds::rtps::FlowControllerImpl<eprosima::fastdds::rtps::FlowControllerPureSyncPublishMode, eprosima::fastdds::rtps::FlowControllerFifoSchedule>::add_new_sample
    (this=0x5555557b1860, writer=0x7fffa8024160, change=0x7fffa8023b10, 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 106179564232877ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp:1087
#14 0x00007ffff6ca4a4b in eprosima::fastdds::rtps::StatelessWriter::unsent_change_added_to_history
    (this=0x7fffa8024160, change=0x7fffa8023b10, 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 106179564232877ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/rtps/writer/StatelessWriter.cpp:301
#15 0x00007ffff6b24c94 in eprosima::fastdds::rtps::WriterHistory::notify_writer (
    this=0x7fffa8023c90, a_change=0x7fffa8023b10, 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 106179564232877ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/rtps/history/WriterHistory.cpp:207
#16 0x00007ffff657428d in eprosima::fastdds::rtps::WriterHistory::add_change_with_commit_hook<eprosima::fastdds::dds::DataWriterImpl::perform_create_new_change(eprosima::fastdds::rtps::ChangeKind_t, void const*, eprosima::fastdds::rtps::WriteParams&, const eprosima::fastdds::dds::InstanceHandle_t&)::<lambda(eprosima::fastdds::dds::DataWriterImpl::CacheChange_t&)> >(eprosima::fastdds::rtps::CacheChange_t *, eprosima::fastdds::rtps::WriteParams &, struct {...}, std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > >) (
    this=0x7fffa8023c90, a_change=0x7fffa8023b10, wparams=..., pre_commit=..., 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 106179564232877ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/include/fastdds/rtps/history/WriterHistory.hpp:299
#17 0x00007ffff6573e2b in eprosima::fastdds::dds::DataWriterHistory::add_pub_change_with_commit_hook<eprosima::fastdds::dds::DataWriterImpl::perform_create_new_change(eprosima::fastdds::rtps::ChangeKind_t, void const*, eprosima::fastdds::rtps::WriteParams&, const eprosima::fastdds::dds::InstanceHandle_t&)::<lambda(eprosima::fastdds::dds::DataWriterImpl::CacheChange_t&)> >(eprosima::fastdds::rtps::CacheChange_t *, eprosima::fastdds::rtps::WriteParams &, struct {...}, std::unique_lock<std::recursive_timed_mutex> &, const std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > &) (this=0x7fffa8023c90, change=0x7fffa8023b10, 
    wparams=..., pre_commit=..., lock=..., 
    max_blocking_time=std::chrono::_V2::steady_clock time_point = { 19779664231689ns })
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/fastdds/publisher/DataWriterHistory.hpp:159
#18 0x00007ffff656bde0 in eprosima::fastdds::dds::DataWriterImpl::perform_create_new_change (
    this=0x7fffa8019310, change_kind=eprosima::fastdds::rtps::NOT_ALIVE_DISPOSED, 
    data=0x7fff90000dd0, wparams=..., handle=...)
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/fastdds/publisher/DataWriterImpl.cpp:1097
#19 0x00007ffff656c614 in eprosima::fastdds::dds::DataWriterImpl::create_new_change_with_params (
    this=0x7fffa8019310, changeKind=eprosima::fastdds::rtps::NOT_ALIVE_DISPOSED, 
    data=0x7fff90000dd0, wparams=..., handle=...)
    at /home/danny/eProsima/DDS-Pipe/src/fastdds/src/cpp/fastdds/publisher/DataWriterImpl.cpp:1193

…ispose/unregister samples

Signed-off-by: danipiza <dpizarrogallego@gmail.com>
Signed-off-by: danipiza <dpizarrogallego@gmail.com>
@codecov-commenter

codecov-commenter commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 36.43%. Comparing base (0fe11b8) to head (e6bbf83).

Files with missing lines Patch % Lines
...s/src/cpp/writer/dds/filter/RepeaterDataFilter.cpp 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #186      +/-   ##
==========================================
+ Coverage   36.20%   36.43%   +0.23%     
==========================================
  Files         174      157      -17     
  Lines       12381     7533    -4848     
  Branches     5655     2992    -2663     
==========================================
- Hits         4483     2745    -1738     
+ Misses       5034     3334    -1700     
+ Partials     2864     1454    -1410     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

zesk1999
zesk1999 previously approved these changes Jun 16, 2026

@zesk1999 zesk1999 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Signed-off-by: danipiza <dpizarrogallego@gmail.com>
@Danipiza Danipiza requested a review from zesk1999 June 18, 2026 05:37
@Danipiza Danipiza changed the title [#24620] Fixed segfault in 'RepeaterDataFilter.cpp' when forwarding dispose/unregister samples [#24620] Fixed segfault in 'RepeaterDataFilter.cpp' when forwarding dispose/unregister samples with a null check Jun 18, 2026
@Danipiza Danipiza merged commit 8eaf047 into main Jun 18, 2026
16 checks passed
@Danipiza Danipiza deleted the fix/dispose branch June 18, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants