Coder Social home page Coder Social logo

rmw_cyclonedds's Introduction

ROS 2 RMW for Eclipse Cyclone DDS

Easy, fast, reliable, small Eclipse Cyclone DDS Tier 1 ROS middleware for ROS 2. Make your 🐢 run like a 🚀 Eclipse Cyclone DDS has great adopters and contributors in the ROS community and is an Eclipse Foundation open source project of Eclipse IoT and OpenADx (autonomous driving).

This package lets ROS 2 use Eclipse Cyclone DDS as the underlying DDS implementation. Cyclone DDS is ready to use. It seeks to give the fastest, easiest, and most robust ROS 2 experience. Let the Cyclone blow you away!

  1. Install:

    apt install ros-eloquent-rmw-cyclonedds-cpp
    

    or

    apt install ros-dashing-rmw-cyclonedds-cpp
    
  2. Set env variable and run ROS 2 apps as usual:

    export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

  3. Confirm RMW: In Eloquent and later, to confirm which RMW you're using:

    ros2 doctor --report

Performance recommendations

With large samples (100s of kilobytes), excessive latency can be caused by running out of space in the OS-level receive buffer. For this reason, on Linux, we recommend increasing the buffer size:

  • Temporarily (until reboot): sudo sysctl -w net.core.rmem_max=8388608 net.core.rmem_default=8388608
  • Permanently: echo "net.core.rmem_max=8388608\nnet.core.rmem_default=8388608\n" | sudo tee /etc/sysctl.d/60-cyclonedds.conf

Debugging

So Cyclone isn't playing nice or not giving you the performance you had hoped for? That's not good... Please file an issue against this repository!

The ddsperf tool distributed with Cyclone DDS can be used to check that communication works without ROS. Run ddsperf sanity on two different machines - if the "mean" value is above 100000us, there are likely network issues.

If you're having trouble with nodes discovering others or can't use multicast at all on your network setup, you can circumvent discovery:

export CYCLONEDDS_URI='<Discovery><Peers><Peer Address='myroshost.local' /><Peer Address='myroshost2.local' /></></>'

Here are some ways to generate additional debugging info that can help identify the problem faster, and are helpful on an issue ticket:

  • Configure Cyclone to create richer debugging output:

    • To see the output live:

      export CYCLONEDDS_URI='<Tracing><Verbosity>trace</><Out>stderr</></>'

    • To send to /var/log/:

      export CYCLONEDDS_URI='<Tracing><Verbosity>trace</><Out>/var/log/cyclonedds.${CYCLONEDDS_PID}.log</></>'

  • Create a Wireshark capture:

    wireshark -k -w wireshark.pcap.gz

Building from source and contributing

The following branches are actively maintained:

  • master, which targets the upcoming ROS version, Foxy
  • dashing-eloquent, which maintains compatibility with ROS releases Dashing and Eloquent

If building ROS 2 from source (ros2.repos), you already have this package and Cyclone DDS:

cd /opt/ros/master
rosdep install --from src -i
colcon build
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

Quality Declaration

This package claims to be in the Quality Level 2 category, see the Quality Declaration for more details.

rmw_cyclonedds's People

Contributors

ahcorde avatar barry-xu-2018 avatar christophebedard avatar clalancette avatar cottsay avatar dirk-thomas avatar dkroenke avatar dpotman avatar eboasson avatar emersonknapp avatar evshary avatar fujitatomoya avatar hidmic avatar iluetkeb avatar ivanpauno avatar jacobperron avatar joespeed avatar karsten1987 avatar lobotuerk avatar marcoag avatar matthiaskillat avatar methyldragon avatar mjcarroll avatar mm318 avatar paudrow avatar rotu avatar sidfaber avatar sloretz avatar sumanth-nirmal avatar voldivh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rmw_cyclonedds's Issues

Implement received timestamp

Originally posted by @eboasson in #163 (comment)

I just wanted to add a suggestion on how to get a receive time stamp without having to rely on Cyclone to provide it.

The RMW layer relies on a custom sample implementation to perform direct ROS2-to-CDR conversion and to get access to the serialized form for rmw_take_serialized_message and any received message will be turned into a sample instance as soon as it is ready to be inserted in the reader history caches. If that’s what you mean by “the receive time stamp” (as I pointed out in ros2/design#259 (comment) there are very many versions), then one way to do it would be to store that time stamp in this custom sample: just add it to

class serdata_rmw : public ddsi_serdata
{
protected:
size_t m_size {0};
/* first two bytes of data is CDR encoding
second two bytes are encoding options */
std::unique_ptr<byte[]> m_data {nullptr};
public:
serdata_rmw(const ddsi_sertopic * topic, ddsi_serdata_kind kind);
void resize(size_t requested_size);
size_t size() const {return m_size;}
void * data() const {return m_data.get();}
};

It won’t be returned in the sample info because cyclone currently only implements the fields defined in the standard, but that can be worked around by using dds_takecdr instead of dds_take, like when taking a serialized message:

while (dds_takecdr(sub->enth, &dcmn, 1, &info, DDS_ANY_STATE) == 1) {

That gives you a reference to the sample that you can then deserialize by calling ddsi_serdata_to_sample on it. That way you get everything.

(I don’t know what the rules are for loaned samples, but with this sample implementation, and for those topics where the CDR representation matches the in-memory representation and where there are no endianness issues, the same trick would be feasible.)

CDR wstring serialization is nonstandard

DDS-XTypes v1.2 – defines the DDS Type System and the serialized representation of DDS data.

Here's what XTypes says about strings, which I think we do a poor job of following:

Objects of String<Char8> type shall be represented using the UTF-8 character encoding. The serialized length of an object of type String shall be the number of bytes in the CDR buffer taken by the String<Char8> characters, including the terminating NUL character. The serialized length may not be the same as the number of Unicode characters because a single Unicode character encoded using the UTF-8 encoding may take one to four bytes.

Objects of String<Char16> type shall be represented using the UTF-16 character encoding. The serialized length of an object of type String<Char16> shall be the number of bytes in the CDR buffer taken by the String<Char16> characters. This is twice the number of characters in the string because a single character (in the Basic Multilingual Plane) encoded using UTF-16 takes 2 bytes to serialize.

The UTF-16 representation of object of type String<Char16> shall not include a Byte Order Mark (BOM). The representation shall also not include any terminating NUL character(s).

Fixing this issue will likely break compatibility with Fast-RTPS (ros2/rmw_connext#364) but fix compatibility with Connext (ros2/build_farmer#268, #121)

Originally posted by @rotu in #42

Client/service identifier and service request header format

Client requests and service responses are serialized by prefixing the serialization of the actual content of the request/response by a request id consisting of the local instance handle of the partiicpant and a 64-bit sequence number.

The way the instance handles are generated means that it is highly likely to be unique, but there is no guarantee, and perhaps it would be better to use the GUID.

Also it would be nice if it matched the format used by other RMW layers to have interoperability, but I don't know what the others do, nor whether there's agreement what it should be.

Serializer copies data a bit more often than necessary

The serialization happens by simply appending to std::vector — I'm sure that's not the most efficient way to do it. At the very least the fixed-size message could have the vector allocated to the correct size from the start.

Crash when subscribing to a single topic with multiple types

Bug report

Required Info:

  • Operating System:
    • Ubuntu Linux 18.04
  • Installation type:
    • ROS Eloquent, from binaries
  • Version or commit hash:
    • 0.4.4-1bionic.20200121.221538
  • DDS implementation:
    • CycloneDDS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

This issue happens when a single node subscribes to a topic multiple times and each subscriber has a different message type.

It's simple to reproduce this with rviz:

. /opt/ros/eloquent/setup.bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 run rviz2 rviz2
  1. Click Add / Pose
  2. Click Add / Marker
  3. Change the Pose plugin's topic to /test
  4. Change the Marker plugin's topic to /test
  5. rviz will crash

Expected behavior

The program should subscribe to the topic without crashing. Each subscriber callback should receive messages published to that topic for the type they expect. Note that FastRTPS behaves correctly.

Actual behavior

The program crashes as soon as the second create_subscription call is made. Furthermore, it does not seem like it is throwing an exception; I tested this this my making my own program that subscribed to a topic multiple times, and I was unable to catch an exception, it appeared as though the program crashed due to SIGABRT being raised.

Additional information

This bug also exists with the binary version in ROS Dashing.

Console output from an example rviz session:

1583786612.521721 [230]      rviz2: using network interface enp21s0 (udp/x.x.x.x) selected arbitrarily from: enp21s0, docker0
[INFO] [rviz2]: Stereo is NOT SUPPORTED
[INFO] [rviz2]: OpenGl version: 4.6 (GLSL 4.6)
[INFO] [rviz2]: Stereo is NOT SUPPORTED
[INFO] [rviz2]: Stereo is NOT SUPPORTED
terminate called after throwing an instance of 'rclcpp::exceptions::RCLError'
  what():  could not create subscription: failed to create topic, at /tmp/binarydeb/ros-eloquent-rmw-cyclonedds-cpp-0.4.4/src/rmw_node.cpp:1446, at /tmp/binarydeb/ros-eloquent-rcl-0.8.4/src/rcl/subscription.c:168

Master CI installing FastRTPS from binary

Discovered when investigating eProsima/Fast-DDS#1173

2020-04-22T17:04:56.5980077Z �[1mexecuting command [sudo -H apt-get install -y ros-eloquent-fastcdr]�[0m
 2020-04-22T17:04:56.5981853Z �[1mexecuting command [sudo -H apt-get install -y ros-eloquent-fastrtps]�[0m

(1) rosdistro isn't Eloquent, so this shouldn't happen
(2) I'm not sure why it's installing FastRTPS from binaries.

rmw_cyclonedds_cpp crashes when receiving a message on /rosout

Bug report

Required Info:

  • Operating System:
    • Ubuntu Linux 18.04
  • Installation type:
    • Binaries
  • Version or commit hash:
    • Dashing:
      • ros-dashing-cyclonedds: 0.1.0-3bionic.20191205.182051
      • ros-dashing-rmw-cyclonedds-cpp: 0.4.2-1bionic.20200318.032607
    • Eloquent:
      • ros-eloquent-cyclonedds: 0.1.0-7bionic.20191213.041258
      • ros-eloquent-rmw-cyclonedds-cpp: 0.4.4-1bionic.20200121.221538
  • DDS implementation:
    • rmw_cyclonedds_cpp
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

  1. Create a rclcpp client that subscribes to rcl_interfaces:msg::Log messages on /rosout using rmw_cyclonedds_cpp
  2. Publish a message to /rosout
    • ros2 topic pub -1 /rosout rcl_interfaces/msg/Log
  3. The client will crash

Here's an example program:

#include <rclcpp/rclcpp.hpp>
#include <rcl_interfaces/msg/log.hpp>
#include <stdio.h>

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared("cyclone_log_test");

  auto sub = node->create_subscription<rcl_interfaces::msg::Log>("/rosout", 1,
      [node](rcl_interfaces::msg::Log::ConstSharedPtr msg) {
    std::cout << "rosout: " << msg->msg << std::endl;
  });
  auto sub2 = node->create_subscription<rcl_interfaces::msg::Log>("/rosout2", 1,
      [node](rcl_interfaces::msg::Log::ConstSharedPtr msg) {
    std::cout << "rosout2: " << msg->msg << std::endl;
  });

  rclcpp::spin(node);
  return 0;
}

Expected behavior

The above client should not crash, but instead print rosout: followed by the log message.

Actual behavior

The client crashes.

Additional information

The problem does not happen when subscribing to other topics. In the above example, it also creates a subscriber on /rosout2, and publishing a log message there will print as expected.

Crashes do not occur when using rmw_fastrtps_cpp, rmw_opensplice_cpp, or rmw_connext_cpp.

gdb catches this stack trace:

realloc(): invalid pointer

Thread 1 "cyclone_log_tes" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff68cf801 in __GI_abort () at abort.c:79
#2  0x00007ffff6918897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff6a45b9a "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff691f90a in malloc_printerr (str=str@entry=0x7ffff6a43efd "realloc(): invalid pointer") at malloc.c:5350
#4  0x00007ffff6927eba in __GI___libc_realloc (oldmem=0x555555809910, bytes=1) at malloc.c:3174
#5  0x00007ffff549c432 in rosidl_generator_c__String__assignn () from /opt/ros/eloquent/lib/librosidl_generator_c.so
#6  0x00007ffff3bc1fa5 in rmw_cyclonedds_cpp::StringHelper<rosidl_typesupport_introspection_c__MessageMembers>::assign (field=0x555555809900, deser=...)
    at ./include/rmw_cyclonedds_cpp/TypeSupport.hpp:86
#7  rmw_cyclonedds_cpp::deserialize_field<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (call_new=false, deser=..., field=0x555555809900, 
    member=0x7ffff03b97e0) at ./include/rmw_cyclonedds_cpp/TypeSupport_impl.hpp:579
#8  rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_c__MessageMembers>::deserializeROSmessage (this=0x5555557c8800, deser=..., members=0x7ffff03b8900, 
    ros_message=0x5555558098f0, call_new=false) at ./include/rmw_cyclonedds_cpp/TypeSupport_impl.hpp:732
#9  0x00007ffff3bdebc1 in rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_c__MessageMembers>::deserializeROSmessage(cycdeser&, void*, std::function<void (cycdeser&)>) (
    this=0x5555557c8800, deser=..., ros_message=ros_message@entry=0x5555558098f0, prefix=...) at ./include/rmw_cyclonedds_cpp/TypeSupport_impl.hpp:907
#10 0x00007ffff3bdcc28 in serdata_rmw_to_sample (dcmn=<optimized out>, sample=0x5555558098f0, bufptr=<optimized out>, buflim=<optimized out>) at ./src/serdata.cpp:282
#11 0x00007ffff393879b in ddsi_serdata_to_sample (buflim=0x0, bufptr=0x0, sample=<optimized out>, d=<optimized out>) at ./src/core/ddsi/include/dds/ddsi/ddsi_serdata.h:199
#12 dds_rhc_take_w_qminv (cond=0x0, handle=<optimized out>, qminv=0, max_samples=1, info_seq=0x7fffffffabc0, values=0x7fffffffabb8, lock=<optimized out>, rhc=0x5555557fc430)
    at ./src/core/ddsc/src/dds_rhc_default.c:2016
#13 dds_rhc_default_take (cond=0x0, handle=<optimized out>, mask=<optimized out>, max_samples=<optimized out>, info_seq=<optimized out>, values=<optimized out>, lock=<optimized out>, 
    rhc=0x5555557fc430) at ./src/core/ddsc/src/dds_rhc_default.c:2640
#14 dds_rhc_default_take_wrap (rhc=0x5555557fc430, lock=<optimized out>, values=0x7fffffffabb8, info_seq=0x7fffffffabc0, max_samples=1, mask=<optimized out>, handle=<optimized out>, 
    cond=0x0) at ./src/core/ddsc/src/dds_rhc_default.c:379
#15 0x00007ffff394187e in dds_rhc_take (cond=<optimized out>, handle=0, mask=128, max_samples=1, info_seq=0x7fffffffabc0, values=0x7fffffffabb8, lock=true, rhc=<optimized out>)
    at ./src/core/ddsc/include/dds/ddsc/dds_rhc.h:83
#16 dds_read_impl (take=take@entry=true, reader_or_condition=<optimized out>, buf=buf@entry=0x7fffffffabb8, bufsz=<optimized out>, maxs=1, si=0x7fffffffabc0, mask=128, hand=0, lock=true, 
    only_reader=false) at ./src/core/ddsc/src/dds_read.c:120
#17 0x00007ffff3941e80 in dds_take (rd_or_cnd=<optimized out>, buf=buf@entry=0x7fffffffabb8, si=si@entry=0x7fffffffabc0, bufsz=bufsz@entry=1, maxs=<optimized out>, maxs@entry=1)
    at ./src/core/ddsc/src/dds_read.c:331
#18 0x00007ffff3bad013 in rmw_take_int (subscription=<optimized out>, ros_message=<optimized out>, taken=0x7fffffffac7f, message_info=0x7fffffffc130) at ./src/rmw_node.cpp:1610
#19 0x00007ffff7860748 in rcl_take () from /opt/ros/eloquent/lib/librcl.so
#20 0x00007ffff7b0fb1a in rclcpp::executor::Executor::execute_subscription(std::shared_ptr<rclcpp::SubscriptionBase>) () from /opt/ros/eloquent/lib/librclcpp.so
#21 0x00007ffff7b11045 in rclcpp::executor::Executor::execute_any_executable(rclcpp::executor::AnyExecutable&) () from /opt/ros/eloquent/lib/librclcpp.so
#22 0x00007ffff7b1771f in rclcpp::executors::SingleThreadedExecutor::spin() () from /opt/ros/eloquent/lib/librclcpp.so
#23 0x00007ffff7b14412 in rclcpp::spin(std::shared_ptr<rclcpp::node_interfaces::NodeBaseInterface>) () from /opt/ros/eloquent/lib/librclcpp.so
#24 0x00007ffff7b146cb in rclcpp::spin(std::shared_ptr<rclcpp::Node>) () from /opt/ros/eloquent/lib/librclcpp.so
#25 0x000055555555e36c in main (argc=1, argv=0x7fffffffd308) at /home/preed/src/ros2/cyclone_log_test/src/cyclone_log_test/src/main.cpp:19

Setting a too-high domain ID results in an opaque error message

When you try to run CycloneDDS with a too-high domain id, you get an uninformative error message. Setting the domain id to a negative number results in a saner message:

ROS_DOMAIN_ID=55000 ros2 topic list

Traceback (most recent call last):
  File "/opt/ros/master/install/bin/ros2", line 11, in <module>
    load_entry_point('ros2cli==0.8.3', 'console_scripts', 'ros2')()
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/cli.py", line 69, in main
    rc = extension.main(parser=parser, args=args)
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2topic/command/topic.py", line 43, in main
    return extension.main(args=args)
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2topic/verb/list.py", line 38, in main
    with NodeStrategy(args) as node:
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/node/strategy.py", line 26, in __init__
    if is_daemon_running(args):
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/node/daemon.py", line 36, in is_daemon_running
    s.bind(addr)
OverflowError: getsockaddrarg: port must be 0-65535.
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 109, in apport_excepthook
    pr.add_proc_info(extraenv=['PYTHONPATH', 'PYTHONHOME'])
  File "/usr/lib/python3/dist-packages/apport/report.py", line 543, in add_proc_info
    self.add_proc_environ(pid, extraenv)
  File "/usr/lib/python3/dist-packages/apport/report.py", line 610, in add_proc_environ
    env = _read_file('environ', dir_fd=proc_pid_fd).replace('\n', '\\n')
  File "/usr/lib/python3/dist-packages/apport/report.py", line 73, in _read_file
    with open(path, 'rb', opener=lambda path, mode: os.open(path, mode, dir_fd=dir_fd)) as fd:
  File "/usr/lib/python3/dist-packages/apport/report.py", line 73, in <lambda>
    with open(path, 'rb', opener=lambda path, mode: os.open(path, mode, dir_fd=dir_fd)) as fd:
TypeError: argument should be integer or None, not list

Original exception was:
Traceback (most recent call last):
  File "/opt/ros/master/install/bin/ros2", line 11, in <module>
    load_entry_point('ros2cli==0.8.3', 'console_scripts', 'ros2')()
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/cli.py", line 69, in main
    rc = extension.main(parser=parser, args=args)
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2topic/command/topic.py", line 43, in main
    return extension.main(args=args)
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2topic/verb/list.py", line 38, in main
    with NodeStrategy(args) as node:
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/node/strategy.py", line 26, in __init__
    if is_daemon_running(args):
  File "/opt/ros/master/install/lib/python3.6/site-packages/ros2cli/node/daemon.py", line 36, in is_daemon_running
    s.bind(addr)
OverflowError: getsockaddrarg: port must be 0-65535.

ROS_DOMAIN_ID=-10 ros2 topic list

[ERROR] [rmw_cyclonedds_cpp]: rmw_create_node: domain id out of range

>>> [rcutils|error_handling.c:107] rcutils_set_error_state()
This error state is being overwritten:

  'error not set, at /opt/ros/master/src/ros2/rcl/rcl/src/rcl/node.c:336'

with this new error message:

  'rcl node's rmw handle is invalid, at /opt/ros/master/src/ros2/rcl/rcl/src/rcl/node.c:485'

rcutils_reset_error() should be called after error handling to avoid this.
<<<
[ERROR] [rcl]: Failed to fini publisher for node: 1
Unknown error creating node: rcl node's rmw handle is invalid, at /opt/ros/master/src/ros2/rcl/rcl/src/rcl/node.c:485

rwm_cyclonedds_cpp ERROR

Hi :
According to the official website install Installing ROS 2 Dashing Diademata source ,and it run 'ros2 run demo_nodes_cpp talker' successfully.
there are libddsc.so.0.5.0 in ros2_dashing/install/cyclonedds/lib, and librmw_cyclonedds_cpp.so in ros2_dashing/install/rwm_cyclonedds_cpp/lib.

export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 doctor --report
[EROOR] [rcl] :Error getting RWM inplementation identifier / RWM inplementation not installed(expected identifier of 'rwm_cyclonedds_cpp') exiting with 1

It need rosidl_typesupport_cyclonedds, doesn't it ?

Not getting service responses reliably when using CycloneDDS

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04, both AMD64 and ARM64
  • Installation type:
    • Binaries and from source
  • Version or commit hash:
    • b92db52bb14ec097946bfe44d2b337359dddfbab (using 4089fee)
  • DDS implementation:
    • CycloneDDS
  • Client library (if applicable):
    • rclcpp only

Steps to reproduce issue

  1. On one terminal, run:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp add_two_ints_server
  1. On another terminal, run:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp add_two_ints_client_async

Expected behavior

A single service call takes place and succeeds i.e. you get logs on each terminal:

[INFO] [add_two_ints_server]: Incoming request
a: 2 b: 3
[INFO] [add_two_ints_client]: Result of add_two_ints: 5

Actual behavior

The client hangs with no output though the server does log so it appears to have received the request.

Additional information

It does not happen on rclpy. It also does not happen if bringing up both nodes via launch e.g.:

from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
    return LaunchDescription([
        Node(
            package='demo_nodes_cpp',
            node_executable='add_two_ints_server',
            output='screen'
        ),
        Node(
            package='demo_nodes_cpp',
            node_executable='add_two_ints_client_async',
            output='screen'
        )
    ])

So it's likely a race.

Deserializer doesn't validate its input

The custom serializer/deserializer that converts between ROS message format and CDR (a derivative of the dynamic FastRTPS RMW layer) doesn't do any form of checking or byteswapping of its input in a mixed-endian network.

CycloneDDS versions

Bug report

Required Info:

  • Operating System:
    • Linux (Ubuntu/bionic)
  • Installation type:
    • From source
  • Version or commit hash:
    • dashing
  • DDS implementation:
    • CycloneDDS
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

// ROS 2 instructions (https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Development-Setup/)

Expected behavior

Everything shall compile without error.

Actual behavior

rwm_cyclonedds_cpp compilation returns an error:

rwm/get_topic_endpoint_info.h: no such file or directory

Additional information


Feature request

I think dashing's ros2.repos should point to particular tags for ros2/rmw_cyclonedds and eclipse-cyclonedds/cyclonedds as in dashing-release branch.

Build failures on Windows in TypeSupport2.hpp

Bug report

Required Info:

  • Operating System:
    • Windows 10
  • Installation type:
    • from source
  • Version or commit hash:
  • DDS implementation:
    • rmw_cyclonedds_cpp
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Example build: https://ci.ros2.org/job/ci_windows/8749/

Expected behavior

Actual behavior

Additional information

I started looking into this and trying the obvious things in https://github.com/ros2/rmw_cyclonedds/tree/nuclearsandwich/include-functional but it's slow going without sitting in front of a Windows machine.

FYI @rotu these build issues look like they were introduced with #42

Following README instructions but rmw_cyclonedds doesn't build

Bug report

Required Info:

  • Operating System:
  • Ubuntu 18.04
  • Installation type:
    • source
  • Version or commit hash:
    -43f70ed
  • DDS implementation:
    • cyclonedds
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Followed directions on the README:

cd ros2_ws/src
git clone https://github.com/atolab/rmw_cyclonedds
git clone https://github.com/eclipse-cyclonedds/cyclonedds
cd ..
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

Expected behavior

Code should build

Actual behavior

I get this build error:

--- stderr: rmw_cyclonedds_cpp
CMake Error at CMakeLists.txt:35 (find_package):
  Could not find a package configuration file provided by "CycloneDDS" with
  any of the following names:

    CycloneDDSConfig.cmake
    cyclonedds-config.cmake

  Add the installation prefix of "CycloneDDS" to CMAKE_PREFIX_PATH or set
  "CycloneDDS_DIR" to a directory containing one of the above files.  If
  "CycloneDDS" provides a separate development package or SDK, be sure it has
  been installed.

Additional information

I also tried removing the rmw_cyclonedds folder from my workspace and just building cyclonedds and I get this error:

--- stderr: CycloneDDS
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/usr/share/maven/lib/guice.jar) to method java.lang.ClassLoer.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
make[2]: *** [src/idlc/target/idlc-jar-with-dependencies.jar] Error 1
make[1]: *** [src/idlc/CMakeFiles/idlc.dir/all] Error 2
make: *** [all] Error 2
---
Failed   <<< CycloneDDS [ Exited with code 2 ]

Using different typesupports on same node and topic ends in segfault

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • From source
  • Version or commit hash:
  • DDS implementation:
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

Run ros1_bridge tests using ros2/ros1_bridge#233.

Expected behavior

Tests pass.

Actual behavior

Tests segfault.

Additional information

Backtrace below
#1  0x00007ffff01d7801 in __GI_abort () at abort.c:79
#2  0x00007ffff01c739a in __assert_fail_base (fmt=0x7ffff034e7d8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
    assertion=assertion@entry=0x7fffe5ca6de8 "str->capacity == str->size + 1",
    file=file@entry=0x7fffe5ca6c40 "/home/michel/Workspaces/ros2_ws/src/ros2/rmw_cyclonedds/rmw_cyclonedds_cpp/src/TypeSupport2.hpp", line=line@entry=402,
    function=function@entry=0x7fffe5ca6f00 <rmw_cyclonedds_cpp::ROSIDLC_StringValueType::data(void const*) const::__PRETTY_FUNCTION__> "virtual rmw_cyclonedds_cpp::TypedSpan<const char> rmw_cyclonedds_cpp::ROSIDLC_StringValueType::data(const void*) const") at assert.c:92
#3  0x00007ffff01c7412 in __GI___assert_fail (assertion=0x7fffe5ca6de8 "str->capacity == str->size + 1",
    file=0x7fffe5ca6c40 "/home/michel/Workspaces/ros2_ws/src/ros2/rmw_cyclonedds/rmw_cyclonedds_cpp/src/TypeSupport2.hpp", line=402,
    function=0x7fffe5ca6f00 <rmw_cyclonedds_cpp::ROSIDLC_StringValueType::data(void const*) const::__PRETTY_FUNCTION__> "virtual rmw_cyclonedds_cpp::TypedSpan<const char> rmw_cyclonedds_cpp::ROSIDLC_StringValueType::data(const void*) const") at assert.c:101
#4  0x00007fffe5c97ffd in rmw_cyclonedds_cpp::ROSIDLC_StringValueType::data(void const*) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#5  0x00007fffe5c93ea8 in rmw_cyclonedds_cpp::CDRWriter::serialize(rmw_cyclonedds_cpp::CDRCursor*, void const*, rmw_cyclonedds_cpp::U8StringValueType const&) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#6  0x00007fffe5c944be in rmw_cyclonedds_cpp::CDRWriter::serialize(rmw_cyclonedds_cpp::CDRCursor*, void const*, rmw_cyclonedds_cpp::AnyValueType const*) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#7  0x00007fffe5c94862 in rmw_cyclonedds_cpp::CDRWriter::serialize(rmw_cyclonedds_cpp::CDRCursor*, void const*, rmw_cyclonedds_cpp::StructValueType const&) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#8  0x00007fffe5c94564 in rmw_cyclonedds_cpp::CDRWriter::serialize(rmw_cyclonedds_cpp::CDRCursor*, void const*, rmw_cyclonedds_cpp::AnyValueType const*) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#9  0x00007fffe5c9352b in rmw_cyclonedds_cpp::CDRWriter::serialize_top_level(rmw_cyclonedds_cpp::CDRCursor*, void const*) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#10 0x00007fffe5c932f4 in rmw_cyclonedds_cpp::CDRWriter::get_serialized_size(void const*) const ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#11 0x00007fffe5c8a431 in serdata_rmw_from_sample(ddsi_sertopic const*, ddsi_serdata_kind, void const*) ()
   from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#12 0x00007fffe595bb57 in ddsi_serdata_from_sample (sample=0x7fffac009c90, kind=<optimized out>, topic=<optimized out>)
    at /home/michel/Workspaces/ros2_ws/src/eclipse-cyclonedds/cyclonedds/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h:179
#13 dds_write_impl (wr=wr@entry=0x7fffac00aa90, data=data@entry=0x7fffac009c90, tstamp=1579131099590500709, action=action@entry=DDS_WR_ACTION_WRITE)
    at /home/michel/Workspaces/ros2_ws/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_write.c:171
#14 0x00007fffe595bccb in dds_write (writer=<optimized out>, data=0x7fffac009c90)
    at /home/michel/Workspaces/ros2_ws/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_write.c:39
#15 0x00007fffe5c309b8 in rmw_publish () from /home/michel/Workspaces/ros2_ws/install/rmw_cyclonedds_cpp/lib/librmw_cyclonedds_cpp.so
#16 0x00007fffefd85197 in rmw_publish () from /home/michel/Workspaces/ros2_ws/install/rmw_implementation/lib/librmw_implementation.so
#17 0x00007ffff73c578b in rcl_publish () from /home/michel/Workspaces/ros2_ws/install/rcl/lib/librcl.so
#18 0x00007ffff53a41d4 in rclcpp::Publisher<rcl_interfaces::msg::Log_<std::allocator<void> >, std::allocator<void> >::do_inter_process_publish(rcl_interfaces::msg::Log_<std::allocator<void> > const&) () from /home/michel/Workspaces/ros2_ws/install/ros1_bridge/lib/libros1_bridge.so

It seems to me that dds_create_topic_arbitrary() is not dealing with the fact that the same topic may be associated with different typesupports. In that sense, this issue is equivalent to ros2/rmw_fastrtps#265.

Name mangling

Topic/type/service/client name mangling is all based on a bit of reverse-engineering of the FastRTPS layer. It is probably compatible, but it would be nice to know the rules.

Also, the "no_demangle" option is completely ignored ...

failing ros1_bridge tests

See https://ci.ros2.org/view/packaging/job/packaging_linux/1675/testReport/ which is trying to run a ROS 1 talker, the ros1_bridge dynamic_bridge, and ROS 2 listener.

The problem for the failure seems pretty similar to ros2/rmw_fastrtps#265. The logging messages are published as a C message containing a string. The actual message exchanged between the talker and listener is a C++ message (based on the same .msg). I assume the first advertised topic will "lock in" the C message type and then falsely try to use the same typesupport to read the C++ message which fails with realloc(): invalid pointer.

On allocations in the data path

Path traversed by a message/sample, annotated with memory allocation activity (the "local
subscription bypass" skips straight from write_sample_gc to rhc_store, which is a
bit of a lie when you look carefully at the code, but that way I get the allocations
correct):

rmw_publish
  |
  v
dds_write
  |
  |  RMW serdata: from_sample
  |    - allocates "serdata" and serializes into it
  |  key to instance_handle mapping (1)
  |    allocates for a unique key
  |    - tkmap_instance (entry in table)
  |    - "topicless serdata" for insertion in table
  |    - possibly resizes hash table
  |    (if no readers, undoes the above)
  |
  v
write_sample_gc
  |        \
  |         \
  |  whc_insert (for reliable data)
  |    - allocates whc_node (2)
  |    - inserts in seq# hash (which may grow hash table)
  |    - adds to seq# interval tree (which may require an interval tree node)
  |    - may push out old samples, which may cause frees
  |    - if keyed: insert in instance_handle hash
  |      - may grow hash table (1)
  |           |
  v           |
transmit_sample
  |           |
  |  allocate and initialise new "xmsg" (3)
  |    - large samples: needs many, for DATAFRAG and HEARTBEATFRAG
  |    - serialised data integrated by-reference
  |    - may also need one for a HEARTBEAT
  |           |
  |  xpack_add called for each "xmsg" to combine into RTPS messages
  |    - fills a (lazily allocated per writer) scatter/gather list
  |    - transmits the packet using sendmsg() when full/flushed
  |    - does release record of samples just sent to track the highest seq#
  |      that was actually transmitted, which may release samples if
  |      they were ACK'd already (unlikely, but possible) (3)
  |           |
  |           |
  |           |
  |           |
  |           |local
  |           |subscriptions
sendmsg       |bypass 
  .           |
  .           |
  .           |
  .           |
nn_rmsg_new   |
  |           |
  |  ensure receive buffer space is available (5)
  |    - may allocate new buffers: data is left in these buffers while
  |      defragmenting or dealing with samples received out-of-order
  |    - these buffers are huge in the default config to reduce number of allocations
  |           |
recvmsg       |
  |           |
  |           |
  v           |
"cracking" (5)|
  |           |
  |  term is an analogy to oil refining: breaking up a message into its constituents
  |  typically allocates memory, typically contiguous with received datagram by
  |  bumping a pointer
  |    - COW receiver state on state changes
  |           |
  |  DATA/DATAFRAG/GAP:
  |    - allocate message defragmenting state
  |    - allocate message reordering state
  |    - (typically GAP doesn't require the above)
  |    - may result in delivering data or discarding fragments, which may free memory
  |           |
  |  ACKNACK: |
  |    - may drop messages from WHC, freeing (2):
  |      - whc_node, interval tree entry, index entries, possibly serdata
  |      - possible "keyless serdata" and instance_handle index entry
  |  ACKNACK/NACKFRAG:
  |    - possibly queues retransmits, GAPs and HEARTBEATs
  |      - allocates "xmsg"s (like data path) (3)
  |      - allocates queue entries (4)
  |      - freed upon sending
  |           |
  |  HEARTBEAT:
  |    - may result in delivering data or discarding fragments, which may free memory
  |           |
  v           |
deliver_user_data
  |           |
  |  RMW serdata: from_ser
  |    - allocates a "serdata" and fills it with serialised data
  |      that is still stored in receive buffers
  |           |
  |  frees receive buffer claims after having created the "serdata" (5)
  |  typical synchronous delivery path without message loss:
  |    - resets receive buffer allocator pointer to what it was prior to processing
  |      datagram
  |    - (but typical is not so interesting in a worst-case analysis ...)
  |           |
  |  key to instance_handle mapping (1)
  |    allocates for a unique key
  |    - tkmap_instance (entry in table)
  |    - "topicless serdata" for insertion in table
  |    - possibly resizes hash table
  |    (if no readers, undoes the above)
  |           /
  |          /
  |         /
  v        /
rhc_store (once per reader)
  |
  |  - allocates new "instance" if instance handle not yet present in its hash table
  |    may grow instance hash table
  |  - allocates new sample (typically, though never for KEEP_LAST with depth 1 nor
  |    for pushing old samples out of the history
  |  - may free RMW serdatas that were pushed out of the history
  |    this won't affect the instance_handle mappings nor the "topicless serdata"
  |    because overwriting data in the history doesn't change the set of keys
  |  - may require insertion of a "registration" in a hash table, which in turn
  |    may require allocating/growing the hash table (the "registration" itself
  |    is not allocated)
  |
  v
dds_take
  |
  |  - RMW serdata: to_sample, deserialises into ROS message provided by the upper
  |    layers
  |  - RMW free of the "serdata" if the refcount drops to zero
  |  - removes the sample from the reader history (possibly the instance as well)
  |    which may involve
  |  - freeing memory allocated for the instance handle mapping and the "topicless
  |    serdata" (1)
  |
  v
rmw_take

There are a number of points worth noting in the above:

  • Cyclone defers freeing memory in some cases, relying on a garbage collector, but this
    garbage collector is one in the sense of the garbage trucks that drive through the
    streets collecting the garbage that has been put on the sidewalk, rather than the
    stop-the-world/"thief in the night" model used in Java, C#, Haskell, &c.

    The deferring is so that some data can be used without having to do reference counting
    for dynamic references caused by using some data for a very short period of time, as
    well as, to some extent, to not incur the cost of freeing at the point of use. This is
    currently used for:

    • mapping entries for key value to instance handle
    • all DDSI-level entities (writers, readers, participants, and their "proxy" variants
      for remote ones)
    • hash table buckets for the concurrent hash tables used to index the above

    Freeing these requires enqueueing them for the garbage collector; that in turn is
    currently implemented by allocating a "gcreq" queue entry.

  • ROS2 only uses keyless topics (in its current versions, anyway) and so there is at most
    a single "instance" and consequently, at most a single instance handle and mapping entry
    at any one time. For administrating these instance handles, the implementation reduces
    the sample to its key value and erases the topic from it (the "topicless serdata" in the
    above). This way, if different topics from the same underlying type implementation have
    the same key value, they get the same instance handle and the same mapping entry.

    The mapping is therefore affected only when the union of the contents of the writer
    history caches and the reader history caches for ROS2 messages transitions between an
    empty set and a non-empty set.

    As there is at most a single entry, it makes sense to force its existence. DDS'
    register_instance can be used to do this (but that thing hasn't really been used in
    Cyclone and I know that I haven't cleaned up the inheritance yet). That will eliminate
    allocations/frees marked (1).

  • The allocations of "whc_node" (marked (2)) for tracking individual samples in the
    writer history cache potentially happen at very high rates (> 1M/s for throughput tests
    with small samples) and I have seen the allocator becomes a bottleneck. Caching is the
    current trick to speed this up; the cache today is bounded by what can reasonably be
    expected to be needed.

    The interval tree is allocated/freed without caching, because there is far less churn
    for those (e.g., for a simple queue, there is only one interval needed).

    The number of samples in the writer history cache is, of course, bounded by history
    settings, and so these could just as easily be pre-allocated. But even better is to use
    the fact that the WHC has been abstracted in the code. A simple pre-allocated circular
    array is sufficient for a implementing a queue with limited depth, and so using a
    different implementation is altogether more sensible.

  • The "xmsg" (marked (3)) that represent RTPS submessages (or more precisely: groups
    of submessages that must be kept together, like an INFO_TS and the DATA it applies to)
    are cached for the same reason the WHC entries are cached. Unlike the latter, the
    lifetime of the "xmsg" is the actual sending of data. The number of "xmsg" that can be
    packed into a message is bounded, and certainly for the data path these can be
    preallocated.

    For generating responses to ACKNACKs and HEARTBEATs and queueing them, maintaining a
    pool with a sensible policy in case the pool is too small should be possible: not
    sending a message in response because no "xmsg" is available is equivalent to it getting
    lost on the network, and that's supported. The "sensible" part of the policy is that it
    may be better to prioritise some types over others, e.g., perhaps it would be better to
    prioritise acknowledgements over retransmits. That's something worth investigating.

  • Responses to received RTPS messages are not sent by the same thread, but rather by a
    separate thread (marked (4)). Retransmits (for example) are generaetd and queued by
    the thread handling the incoming packet, but (for example) ACKNACKs are generated by
    rescheduling a pre-existing event that then generates an "xmsg" in that separate thread
    and transmits it similar to regular data transmission.

    Pre-allocating the queue entries (or better yet: turning the queue into a circular
    array!) has similar considerations to pre-allocating the "xmsg".

  • Receive buffers are troublesome (marked (5)): to support platforms without
    scatter/gather support in the kernel (are there still any left?) it allocates large
    chunks of memory so it can accept a full UDP datagram in it with some room to spare.
    That room to spare is then used to store data generated as a consequence of interpreting
    the packet: receiver state, sample information, administration for tracking fragments or
    samples that were received out of order. Data is the longest lived of all this, and so
    releasing the memory happens when all data in the buffer has been delivered (or
    discarded).

    If fragmented data is received or data is received out-of-order, that means the packets
    can hang around for a while ... The benefit (and primary reason why I made this
    experiment way back when) is that there is no copying of anything until the received
    data is turned into "serdata"s by from_ser (which is implemented in the RMW layer
    for ROS2 messages). Even at that stage, it is still possible to not copy the data but
    instead leave it in the receive buffer, but I have never actually tried that!

    The allocator used within the buffers is a simple bump allocator with an optimisation
    that it resets completely if no part of the packet remains live after processing all its
    submessages, and so for non-fragmented data with negligible packet loss, you're
    basically never allocating memory. Conversely, when data is fragmented or there is
    significant packet loss, it becomes a bit of a mess.

    Eliminating the allocating and freeing of these buffers needs some thought ... quite
    possibly the best way is to assume scatter/gather support and accept an additional copy
    if the data can't be delivered to the reader history immediately.

  • The reader history cache is really vastly overcomplicated for ROS2 use ... similar to
    the writer history cache, it can be replaced by an alternate implementation, and that's
    probably the most straightforward path to eliminating allocations when using ROS2.
    Alternatively, one could pre-allocate instances and samples.

    The "registrations" that track which writer is writing which instances do not incur any
    allocations unless there are multiple writers writing the same instance. Cyclone
    follows the DDS spec in treating topics that have no key fields as topics having a
    single instance, and so multiple ROS2 publishers for the same topic will cause these to
    be tracked. As ROS2 has no concept of registrations and alive/not-alive instances, it
    is probably sensible to have a way of turning this off when using the default RHC
    implementation.

Incomplete QoS Implementation

Bug report

There are currently a family of tests that fail in CI when using rmw_cyclonedds related to QoS. This is likely due to an incomplete or incorrect implementation of some of the QoS features.

The tests are:

Example Linux CI job with these tests failing: http://build.ros2.org/view/Eci/job/Eci__nightly-extra-rmw-release_ubuntu_bionic_amd64/134/testReport/

rmw cyclonedds implementation does not use asynchronous publishing

As discussed elsewhere (ros2/rmw_fastrtps#343 (review)), the current best practice is to use the closest equivalent to the asynchronous publishing mode that some DDS implementations have for implementing rmw_publish(). Right now, this repository does not change the QoS for this when creating a publisher and therefore I assume it uses something like the synchronous publishing mode.

So a few questions:

  • does cyclone have an "asynchronous publishing mode"-like setting?
  • if not, what is the blocking behavior of publishing in cyclone, or more generally what happens when you call publish?

If there is an equivalent mode then it would be best to switch to it by default, even if it has a negative performance impact for some cases.

We can/should separately decide if the best practice should be adjusted, but until that time we should try to keep our rmw implementations as consistent as possible.


And for some more background...

We prefer the asynchronous publishing mode (for now) because:

We're aware that there are performance (latency and throughput) considerations here, and we've already discussed having an option in the ROS API to allow this to be configurable, see: ros2/ros2#255, or at least dynamic (smarter), see: ros2/rmw_connext#190.

But until we decide to change something (and therefore change all the implementations together), I consider this a bug in the implementation of rmw_cyclonedds_cpp, i.e. that it does not implement publish with an "asynchronous publishing mode"-like mode (note this is not part of the DDS standard as far as I can see, but it is a common configuration).

CycloneDDS hangs on exit in Windows

Bug report

Required Info:

  • Operating System:
    • Windows Server 2019
  • Installation type:
    • From source
  • Version or commit hash:
  • DDS implementation:
    • CycloneDDS
  • Client library (if applicable):
    • rclpy

Steps to reproduce issue

  1. Spin up node, in one terminal:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp talker
  1. Try to list topics bypassing the daemon:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 topic list --no-daemon

Expected behavior

Discovered topics (zero or more) are printed on screen and ros2 topic exits.

Actual behavior

ros2 topic hangs and does not react to Ctrl+C anymore

Additional information

CycloneDDS trace for the hung process can be found here.

It may or may not be related to ros2/build_farmer#248 and ros2/rclpy#470.

Talker example crashes on Dashing

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04.2 LTS
  • Installation type:
    • binaries
  • Version or commit hash:
  • DDS implementation:
    • rmw_cyclonedds
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

I'm having problems running the talker/listener example on Dashing. I'm running this on Docker using the image osrf/ros2:nightly that currently has ROS 2 dashing installed. I'm installing rmw_cyclonedds_cpp as follows:

mkdir -p /opt/workspace/src
cd /opt/workspace

export CYCLONE_DDS_ROOT='/opt/cyclonedds'
echo "Installing Cyclone DDS at [${CYCLONE_DDS_ROOT}]"
mkdir -p "${CYCLONE_DDS_ROOT}"
mkdir -p "${CYCLONE_DDS_ROOT}-src"
pushd "${CYCLONE_DDS_ROOT}-src"
git clone https://github.com/eclipse-cyclonedds/cyclonedds.git

apt-get install maven default-jdk -y
mkdir cyclonedds/build
pushd cyclonedds/build
cmake -DCMAKE_INSTALL_PREFIX="${CYCLONE_DDS_ROOT}" ../src/
cmake --build .
cmake --build . --target install
popd
popd

export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${CYCLONE_DDS_ROOT}/lib

pushd src
git clone https://github.com/atolab/rmw_cyclonedds.git
popd
rosdep update && rosdep install --from-paths src/rmw_cyclonedds --ignore-src -r -y
colcon build --packages-up-to rmw_cyclonedds_cpp --merge-install

The program shows an error message when I close the program with Ctrl+C:

source /opt/ros/dashing/setup.bash
source /opt/workspace/install/local_setup.bash
CYCLONE_DDS_ROOT='/opt/cyclonedds'
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${CYCLONE_DDS_ROOT}/lib

RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 1'
...
[INFO] [talker]: Publishing: 'Hello World: 16'
^C[INFO] [rclcpp]: signal_handler(signal_value=2)
[ERROR] [rmw_cyclonedds_cpp]: failed to trigger graph guard condition

# In another terminal
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_py listener
[INFO] [listener]: I heard: [Hello World: 1]
...
KeyboardInterrupt
[ERROR] [rmw_cyclonedds_cpp]: failed to trigger graph guard condition
^C

Also, when I launch first launch the talker, and then the listener, the talker sometimes crashes with a segfault.

root@ub80c134adc2254:/opt/workspace# RMW_IMPLEMENTATION=rmw_cyclonedds_cpp /opt/ros/dashing/lib/demo_nodes_cpp/talker
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
[INFO] [talker]: Publishing: 'Hello World: 4'
[INFO] [talker]: Publishing: 'Hello World: 5'
Segmentation fault (core dumped)
root@ub80c134adc2254:/opt/workspace# 

Expected behavior

  • The talker node should keep running and publishing messages when I launch the listener node.
  • The talker node should shut down without an error message when I stop it with Ctrl+C
  • The listener node should shut down without an error message when I stop it with Ctrl+C

Actual behavior

  • The talker node crashes with Segmentation fault (core dumped) when I launch the listener node.
  • The talker node prints a message [ERROR] [rmw_cyclonedds_cpp]: failed to trigger graph guard condition when I stop it with Ctrl+C
  • The listener node prints a message [ERROR] [rmw_cyclonedds_cpp]: failed to trigger graph guard condition when I stop it with Ctrl+C.

Additional information

Using valgrind I can see more details:

RMW_IMPLEMENTATION=rmw_cyclonedds_cpp /opt/ros/dashing/lib/demo_nodes_cpp/talker

RMW_IMPLEMENTATION=rmw_cyclonedds_cpp /opt/ros/dashing/lib/demo_nodes_cpp/listener

This is the output when the talker crashes by itself after launching a listener

root@ub80c134adc2254:/opt/workspace# RMW_IMPLEMENTATION=rmw_cyclonedds_cpp valgrind /opt/ros/dashing/lib/demo_nodes_cpp/talker
==16717== Memcheck, a memory error detector
==16717== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16717== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16717== Command: /opt/ros/dashing/lib/demo_nodes_cpp/talker
==16717== 
==16717== Thread 6 tev:
==16717== Syscall param sendmsg(msg.msg_iov[2]) points to uninitialised byte(s)
==16717==    at 0x5E92D37: sendmsg (sendmsg.c:28)
==16717==    by 0x9576038: ddsrt_sendmsg (socket.c:534)
==16717==    by 0x9514859: ddsi_udp_conn_write (ddsi_udp.c:149)
==16717==    by 0x9550F4D: ddsi_conn_write (ddsi_tran.h:234)
==16717==    by 0x9550F4D: nn_xpack_send1 (q_xmsg.c:1290)
==16717==    by 0x956FB5C: ddsrt_avl_walk (avl.c:649)
==16717==    by 0x951A0AE: addrset_forall_count (q_addrset.c:530)
==16717==    by 0x95517C6: nn_xpack_send_real.part.2 (q_xmsg.c:1391)
==16717==    by 0x9552C49: nn_xpack_addmsg (q_xmsg.c:1636)
==16717==    by 0x954E6D3: handle_xevk_msg (q_xevent.c:562)
==16717==    by 0x954E6D3: handle_individual_xevent_nt (q_xevent.c:1216)
==16717==    by 0x954F1A9: handle_nontimed_xevent (q_xevent.c:1261)
==16717==    by 0x954F1A9: handle_xevents (q_xevent.c:1312)
==16717==    by 0x954F1A9: xevent_thread (q_xevent.c:1340)
==16717==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16717==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16717==  Address 0x912be1c is 300 bytes inside a block of size 496 alloc'd
==16717==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x9574BE8: ddsrt_realloc (heap.c:65)
==16717==    by 0x951727B: serdata_default_append (ddsi_serdata_default.c:94)
==16717==    by 0x951727B: serdata_default_append_aligned (ddsi_serdata_default.c:111)
==16717==    by 0x951727B: serdata_default_append_blob.constprop.0 (ddsi_serdata_default.c:121)
==16717==    by 0x95172FE: serdata_default_from_sample_plist (ddsi_serdata_default.c:456)
==16717==    by 0x951E815: ddsi_serdata_from_sample (ddsi_serdata.h:167)
==16717==    by 0x951E815: write_mpayload (q_ddsi_discovery.c:179)
==16717==    by 0x951F72A: spdp_write (q_ddsi_discovery.c:324)
==16717==    by 0x9529DD5: new_participant_guid (q_entity.c:636)
==16717==    by 0x9554C0A: dds_create_participant (dds_participant.c:186)
==16717==    by 0x925808D: ref_ppant() (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x925BCFE: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x5191B9D: __rcl_guard_condition_init_from_rmw_impl (guard_condition.c:86)
==16717==    by 0x4EEA338: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:48)
==16717== 
==16717== Syscall param sendmsg(msg.msg_iov[5]) points to uninitialised byte(s)
==16717==    at 0x5E92D37: sendmsg (sendmsg.c:28)
==16717==    by 0x9576038: ddsrt_sendmsg (socket.c:534)
==16717==    by 0x9514859: ddsi_udp_conn_write (ddsi_udp.c:149)
==16717==    by 0x9550F4D: ddsi_conn_write (ddsi_tran.h:234)
==16717==    by 0x9550F4D: nn_xpack_send1 (q_xmsg.c:1290)
==16717==    by 0x956FB5C: ddsrt_avl_walk (avl.c:649)
==16717==    by 0x951A0AE: addrset_forall_count (q_addrset.c:530)
==16717==    by 0x95517C6: nn_xpack_send_real.part.2 (q_xmsg.c:1391)
==16717==    by 0x9552C49: nn_xpack_addmsg (q_xmsg.c:1636)
==16717==    by 0x954E6D3: handle_xevk_msg (q_xevent.c:562)
==16717==    by 0x954E6D3: handle_individual_xevent_nt (q_xevent.c:1216)
==16717==    by 0x954F1A9: handle_nontimed_xevent (q_xevent.c:1261)
==16717==    by 0x954F1A9: handle_xevents (q_xevent.c:1312)
==16717==    by 0x954F1A9: xevent_thread (q_xevent.c:1340)
==16717==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16717==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16717==  Address 0x9137e1c is 300 bytes inside a block of size 496 alloc'd
==16717==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x9574BE8: ddsrt_realloc (heap.c:65)
==16717==    by 0x951727B: serdata_default_append (ddsi_serdata_default.c:94)
==16717==    by 0x951727B: serdata_default_append_aligned (ddsi_serdata_default.c:111)
==16717==    by 0x951727B: serdata_default_append_blob.constprop.0 (ddsi_serdata_default.c:121)
==16717==    by 0x95172FE: serdata_default_from_sample_plist (ddsi_serdata_default.c:456)
==16717==    by 0x951E815: ddsi_serdata_from_sample (ddsi_serdata.h:167)
==16717==    by 0x951E815: write_mpayload (q_ddsi_discovery.c:179)
==16717==    by 0x951F72A: spdp_write (q_ddsi_discovery.c:324)
==16717==    by 0x9529DD5: new_participant_guid (q_entity.c:636)
==16717==    by 0x9554C0A: dds_create_participant (dds_participant.c:186)
==16717==    by 0x925880E: rmw_create_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x51965CC: rcl_node_init (node.c:321)
==16717==    by 0x4EEA3C1: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:66)
==16717==    by 0x4EE3D0D: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:116)
==16717== 
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
[INFO] [talker]: Publishing: 'Hello World: 4'
[INFO] [talker]: Publishing: 'Hello World: 5'
[INFO] [talker]: Publishing: 'Hello World: 6'
[INFO] [talker]: Publishing: 'Hello World: 7'
[INFO] [talker]: Publishing: 'Hello World: 8'
[INFO] [talker]: Publishing: 'Hello World: 9'
[INFO] [talker]: Publishing: 'Hello World: 10'
==16717== Syscall param sendmsg(msg.msg_iov[8]) points to uninitialised byte(s)
==16717==    at 0x5E92D37: sendmsg (sendmsg.c:28)
==16717==    by 0x9576038: ddsrt_sendmsg (socket.c:534)
==16717==    by 0x9514859: ddsi_udp_conn_write (ddsi_udp.c:149)
==16717==    by 0x9550F4D: ddsi_conn_write (ddsi_tran.h:234)
==16717==    by 0x9550F4D: nn_xpack_send1 (q_xmsg.c:1290)
==16717==    by 0x95516EE: nn_xpack_send_real.part.2 (q_xmsg.c:1379)
==16717==    by 0x954F33B: xevent_thread (q_xevent.c:1343)
==16717==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16717==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16717==    by 0x63746DA: start_thread (pthread_create.c:463)
==16717==    by 0x5E9188E: clone (clone.S:95)
==16717==  Address 0x912be1c is 300 bytes inside a block of size 496 alloc'd
==16717==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x9574BE8: ddsrt_realloc (heap.c:65)
==16717==    by 0x951727B: serdata_default_append (ddsi_serdata_default.c:94)
==16717==    by 0x951727B: serdata_default_append_aligned (ddsi_serdata_default.c:111)
==16717==    by 0x951727B: serdata_default_append_blob.constprop.0 (ddsi_serdata_default.c:121)
==16717==    by 0x95172FE: serdata_default_from_sample_plist (ddsi_serdata_default.c:456)
==16717==    by 0x951E815: ddsi_serdata_from_sample (ddsi_serdata.h:167)
==16717==    by 0x951E815: write_mpayload (q_ddsi_discovery.c:179)
==16717==    by 0x951F72A: spdp_write (q_ddsi_discovery.c:324)
==16717==    by 0x9529DD5: new_participant_guid (q_entity.c:636)
==16717==    by 0x9554C0A: dds_create_participant (dds_participant.c:186)
==16717==    by 0x925808D: ref_ppant() (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x925BCFE: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x5191B9D: __rcl_guard_condition_init_from_rmw_impl (guard_condition.c:86)
==16717==    by 0x4EEA338: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:48)
==16717== 
[INFO] [talker]: Publishing: 'Hello World: 11'
==16717== Syscall param sendmsg(msg.msg_iov[6]) points to uninitialised byte(s)
==16717==    at 0x5E92D37: sendmsg (sendmsg.c:28)
==16717==    by 0x9576038: ddsrt_sendmsg (socket.c:534)
==16717==    by 0x9514859: ddsi_udp_conn_write (ddsi_udp.c:149)
==16717==    by 0x9550F4D: ddsi_conn_write (ddsi_tran.h:234)
==16717==    by 0x9550F4D: nn_xpack_send1 (q_xmsg.c:1290)
==16717==    by 0x95516EE: nn_xpack_send_real.part.2 (q_xmsg.c:1379)
==16717==    by 0x954F33B: xevent_thread (q_xevent.c:1343)
==16717==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16717==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16717==    by 0x63746DA: start_thread (pthread_create.c:463)
==16717==    by 0x5E9188E: clone (clone.S:95)
==16717==  Address 0x9144f25 is 133 bytes inside a block of size 240 alloc'd
==16717==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x9574B68: ddsrt_malloc (heap.c:26)
==16717==    by 0x9516E39: serdata_default_allocnew (ddsi_serdata_default.c:243)
==16717==    by 0x9516E39: serdata_default_new_size (ddsi_serdata_default.c:254)
==16717==    by 0x95175D7: serdata_default_new (ddsi_serdata_default.c:262)
==16717==    by 0x95175D7: serdata_default_from_sample_rawcdr (ddsi_serdata_default.c:510)
==16717==    by 0x954F2C6: ddsi_serdata_from_sample (ddsi_serdata.h:167)
==16717==    by 0x954F2C6: write_pmd_message (q_xevent.c:1126)
==16717==    by 0x954F2C6: handle_xevk_pmd_update (q_xevent.c:1146)
==16717==    by 0x954F2C6: handle_individual_xevent (q_xevent.c:1200)
==16717==    by 0x954F2C6: handle_timed_xevent (q_xevent.c:1242)
==16717==    by 0x954F2C6: handle_xevents (q_xevent.c:1300)
==16717==    by 0x954F2C6: xevent_thread (q_xevent.c:1340)
==16717==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16717==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16717==    by 0x63746DA: start_thread (pthread_create.c:463)
==16717==    by 0x5E9188E: clone (clone.S:95)
==16717== 
==16717== Thread 1:
==16717== Invalid write of size 8
==16717==    at 0x4C367E3: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x58F3FB3: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==16717==    by 0x9265DDC: cycdeser::deserialize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926596E: cycdeser::operator>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x927387F: void rmw_cyclonedds_cpp::deserialize_field<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rosidl_typesupport_introspection_cpp::MessageMember const*, void*, cycdeser&, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926CAF4: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926CC18: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x9268E62: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, void*, std::function<void (cycdeser&)>) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x92B2CF3: serdata_rmw_to_sample(ddsi_serdata const*, void*, void**, void*) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x955CA2A: ddsi_serdata_to_sample (ddsi_serdata.h:187)
==16717==    by 0x955CA2A: dds_rhc_take_w_qminv (dds_rhc.c:1929)
==16717==    by 0x955CA2A: dds_rhc_take (dds_rhc.c:2584)
==16717==    by 0x9564728: dds_read_impl (dds_read.c:180)
==16717==    by 0x9564D9F: dds_take (dds_read.c:489)
==16717==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==16717== 
==16717== 
==16717== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==16717==  Access not within mapped region at address 0x0
==16717==    at 0x4C367E3: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16717==    by 0x58F3FB3: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==16717==    by 0x9265DDC: cycdeser::deserialize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926596E: cycdeser::operator>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x927387F: void rmw_cyclonedds_cpp::deserialize_field<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rosidl_typesupport_introspection_cpp::MessageMember const*, void*, cycdeser&, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926CAF4: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x926CC18: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x9268E62: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, void*, std::function<void (cycdeser&)>) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x92B2CF3: serdata_rmw_to_sample(ddsi_serdata const*, void*, void**, void*) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16717==    by 0x955CA2A: ddsi_serdata_to_sample (ddsi_serdata.h:187)
==16717==    by 0x955CA2A: dds_rhc_take_w_qminv (dds_rhc.c:1929)
==16717==    by 0x955CA2A: dds_rhc_take (dds_rhc.c:2584)
==16717==    by 0x9564728: dds_read_impl (dds_read.c:180)
==16717==    by 0x9564D9F: dds_take (dds_read.c:489)
==16717==  If you believe this happened as a result of a stack
==16717==  overflow in your program's main thread (unlikely but
==16717==  possible), you can try to increase the size of the
==16717==  main thread stack using the --main-stacksize= flag.
==16717==  The main thread stack size used in this run was 8388608.
==16717== 
==16717== HEAP SUMMARY:
==16717==     in use at exit: 3,658,341 bytes in 2,309 blocks
==16717==   total heap usage: 4,706 allocs, 2,397 frees, 4,216,595 bytes allocated
==16717== 
==16717== LEAK SUMMARY:
==16717==    definitely lost: 0 bytes in 0 blocks
==16717==    indirectly lost: 0 bytes in 0 blocks
==16717==      possibly lost: 21,150 bytes in 23 blocks
==16717==    still reachable: 3,637,191 bytes in 2,286 blocks
==16717==         suppressed: 0 bytes in 0 blocks
==16717== Rerun with --leak-check=full to see details of leaked memory
==16717== 
==16717== For counts of detected and suppressed errors, rerun with: -v
==16717== Use --track-origins=yes to see where uninitialised values come from
==16717== ERROR SUMMARY: 12 errors from 5 contexts (suppressed: 0 from 0)
Segmentation fault
root@ub80c134adc2254:/opt/workspace# 

This is the output when I just launch the talker, wait until it sends 3 messages, and then use Ctrl+C to stop it:

root@ub80c134adc2254:/opt/workspace# RMW_IMPLEMENTATION=rmw_cyclonedds_cpp valgrind /opt/ros/dashing/lib/demo_nodes_cpp/talker
==16748== Memcheck, a memory error detector
==16748== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16748== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16748== Command: /opt/ros/dashing/lib/demo_nodes_cpp/talker
==16748== 
==16748== Thread 6 tev:
==16748== Syscall param sendmsg(msg.msg_iov[2]) points to uninitialised byte(s)
==16748==    at 0x5E92D37: sendmsg (sendmsg.c:28)
==16748==    by 0x9576038: ddsrt_sendmsg (socket.c:534)
==16748==    by 0x9514859: ddsi_udp_conn_write (ddsi_udp.c:149)
==16748==    by 0x9550F4D: ddsi_conn_write (ddsi_tran.h:234)
==16748==    by 0x9550F4D: nn_xpack_send1 (q_xmsg.c:1290)
==16748==    by 0x956FB5C: ddsrt_avl_walk (avl.c:649)
==16748==    by 0x951A0AE: addrset_forall_count (q_addrset.c:530)
==16748==    by 0x95517C6: nn_xpack_send_real.part.2 (q_xmsg.c:1391)
==16748==    by 0x9552C49: nn_xpack_addmsg (q_xmsg.c:1636)
==16748==    by 0x954E6D3: handle_xevk_msg (q_xevent.c:562)
==16748==    by 0x954E6D3: handle_individual_xevent_nt (q_xevent.c:1216)
==16748==    by 0x954F1A9: handle_nontimed_xevent (q_xevent.c:1261)
==16748==    by 0x954F1A9: handle_xevents (q_xevent.c:1312)
==16748==    by 0x954F1A9: xevent_thread (q_xevent.c:1340)
==16748==    by 0x954B596: create_thread_wrapper (q_thread.c:192)
==16748==    by 0x95768D7: os_startRoutineWrapper (threads.c:151)
==16748==  Address 0x912c67c is 300 bytes inside a block of size 496 alloc'd
==16748==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x9574BE8: ddsrt_realloc (heap.c:65)
==16748==    by 0x951727B: serdata_default_append (ddsi_serdata_default.c:94)
==16748==    by 0x951727B: serdata_default_append_aligned (ddsi_serdata_default.c:111)
==16748==    by 0x951727B: serdata_default_append_blob.constprop.0 (ddsi_serdata_default.c:121)
==16748==    by 0x95172FE: serdata_default_from_sample_plist (ddsi_serdata_default.c:456)
==16748==    by 0x951E815: ddsi_serdata_from_sample (ddsi_serdata.h:167)
==16748==    by 0x951E815: write_mpayload (q_ddsi_discovery.c:179)
==16748==    by 0x951F72A: spdp_write (q_ddsi_discovery.c:324)
==16748==    by 0x9529DD5: new_participant_guid (q_entity.c:636)
==16748==    by 0x9554C0A: dds_create_participant (dds_participant.c:186)
==16748==    by 0x925808D: ref_ppant() (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x925BCFE: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x5191B9D: __rcl_guard_condition_init_from_rmw_impl (guard_condition.c:86)
==16748==    by 0x4EEA338: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:48)
==16748== 
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
^C[INFO] [rclcpp]: signal_handler(signal_value=2)
==16748== Thread 1:
==16748== Invalid read of size 8
==16748==    at 0x925BE58: rmw_trigger_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258267: ggcallback(int, void*) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9555930: dds_reader_data_available_cb (dds_reader.c:199)
==16748==    by 0x955B184: dds_rhc_store (dds_rhc.c:1451)
==16748==    by 0x956A445: try_store (dds_write.c:79)
==16748==    by 0x956A57C: deliver_locally (dds_write.c:110)
==16748==    by 0x956ABEA: dds_writecdr_impl_lowlevel (dds_write.c:232)
==16748==    by 0x952B4A2: delete_reader (q_entity.c:3421)
==16748==    by 0x9555672: dds_reader_close (dds_reader.c:62)
==16748==    by 0x9560B07: dds_delete_impl (dds_entity.c:222)
==16748==    by 0x9560A8C: dds_delete_impl (dds_entity.c:207)
==16748==    by 0x9560C56: dds_delete_impl (dds_entity.c:207)
==16748==  Address 0x9139d70 is 0 bytes inside a block of size 24 free'd
==16748==    at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BE18: rmw_destroy_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258D7E: rmw_destroy_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x5196BC4: rcl_node_fini (node.c:432)
==16748==    by 0x4EE9859: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::{lambda(rcl_node_t*)#2}::operator()(rcl_node_t*) const [clone .isra.17] (node_base.cpp:125)
==16748==    by 0x4EE9EF0: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE9EF0: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE9EF0: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE9EF0: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE9EF0: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:141)
==16748==    by 0x4EE9FF8: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:153)
==16748==    by 0x4EE0D77: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE0D77: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE0D77: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE0D77: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE0D77: rclcpp::Node::~Node() (node.cpp:195)
==16748==    by 0x110B75: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
==16748==    by 0x10E681: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x10E681: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x10E681: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x10E681: main (talker.cpp:98)
==16748==  Block was alloc'd at
==16748==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BD4B: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x92588A1: rmw_create_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x51965CC: rcl_node_init (node.c:321)
==16748==    by 0x4EEA3C1: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:66)
==16748==    by 0x4EE3D0D: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:116)
==16748==    by 0x4EE58F0: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:103)
==16748==    by 0x112AEE: Talker::Talker(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (talker.cpp:43)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:136)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:475)
==16748==    by 0x1136ED: _Sp_counted_ptr_inplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:526)
==16748==    by 0x1136ED: __shared_count<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:637)
==16748==    by 0x1136ED: std::__shared_ptr<Talker, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(std::_Sp_make_shared_tag, std::allocator<Talker> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (shared_ptr_base.h:1295)
==16748==    by 0x10E5CB: shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:344)
==16748==    by 0x10E5CB: allocate_shared<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:691)
==16748==    by 0x10E5CB: make_shared<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:707)
==16748==    by 0x10E5CB: main (talker.cpp:98)
==16748== 
==16748== Invalid read of size 8
==16748==    at 0x925BE8A: rmw_trigger_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258267: ggcallback(int, void*) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9555930: dds_reader_data_available_cb (dds_reader.c:199)
==16748==    by 0x955B184: dds_rhc_store (dds_rhc.c:1451)
==16748==    by 0x956A445: try_store (dds_write.c:79)
==16748==    by 0x956A57C: deliver_locally (dds_write.c:110)
==16748==    by 0x956ABEA: dds_writecdr_impl_lowlevel (dds_write.c:232)
==16748==    by 0x952B4A2: delete_reader (q_entity.c:3421)
==16748==    by 0x9555672: dds_reader_close (dds_reader.c:62)
==16748==    by 0x9560B07: dds_delete_impl (dds_entity.c:222)
==16748==    by 0x9560A8C: dds_delete_impl (dds_entity.c:207)
==16748==    by 0x9560C56: dds_delete_impl (dds_entity.c:207)
==16748==  Address 0x9139d78 is 8 bytes inside a block of size 24 free'd
==16748==    at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BE18: rmw_destroy_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258D7E: rmw_destroy_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x5196BC4: rcl_node_fini (node.c:432)
==16748==    by 0x4EE9859: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::{lambda(rcl_node_t*)#2}::operator()(rcl_node_t*) const [clone .isra.17] (node_base.cpp:125)
==16748==    by 0x4EE9EF0: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE9EF0: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE9EF0: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE9EF0: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE9EF0: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:141)
==16748==    by 0x4EE9FF8: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:153)
==16748==    by 0x4EE0D77: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE0D77: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE0D77: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE0D77: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE0D77: rclcpp::Node::~Node() (node.cpp:195)
==16748==    by 0x110B75: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
==16748==    by 0x10E681: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x10E681: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x10E681: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x10E681: main (talker.cpp:98)
==16748==  Block was alloc'd at
==16748==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BD4B: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x92588A1: rmw_create_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x51965CC: rcl_node_init (node.c:321)
==16748==    by 0x4EEA3C1: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:66)
==16748==    by 0x4EE3D0D: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:116)
==16748==    by 0x4EE58F0: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:103)
==16748==    by 0x112AEE: Talker::Talker(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (talker.cpp:43)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:136)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:475)
==16748==    by 0x1136ED: _Sp_counted_ptr_inplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:526)
==16748==    by 0x1136ED: __shared_count<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:637)
==16748==    by 0x1136ED: std::__shared_ptr<Talker, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(std::_Sp_make_shared_tag, std::allocator<Talker> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (shared_ptr_base.h:1295)
==16748==    by 0x10E5CB: shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:344)
==16748==    by 0x10E5CB: allocate_shared<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:691)
==16748==    by 0x10E5CB: make_shared<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:707)
==16748==    by 0x10E5CB: main (talker.cpp:98)
==16748== 
==16748== Invalid read of size 4
==16748==    at 0x925BE96: rmw_trigger_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258267: ggcallback(int, void*) (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9555930: dds_reader_data_available_cb (dds_reader.c:199)
==16748==    by 0x955B184: dds_rhc_store (dds_rhc.c:1451)
==16748==    by 0x956A445: try_store (dds_write.c:79)
==16748==    by 0x956A57C: deliver_locally (dds_write.c:110)
==16748==    by 0x956ABEA: dds_writecdr_impl_lowlevel (dds_write.c:232)
==16748==    by 0x952B4A2: delete_reader (q_entity.c:3421)
==16748==    by 0x9555672: dds_reader_close (dds_reader.c:62)
==16748==    by 0x9560B07: dds_delete_impl (dds_entity.c:222)
==16748==    by 0x9560A8C: dds_delete_impl (dds_entity.c:207)
==16748==    by 0x9560C56: dds_delete_impl (dds_entity.c:207)
==16748==  Address 0x9139ab0 is 0 bytes inside a block of size 4 free'd
==16748==    at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BE07: rmw_destroy_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x9258D7E: rmw_destroy_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x5196BC4: rcl_node_fini (node.c:432)
==16748==    by 0x4EE9859: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::{lambda(rcl_node_t*)#2}::operator()(rcl_node_t*) const [clone .isra.17] (node_base.cpp:125)
==16748==    by 0x4EE9EF0: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE9EF0: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE9EF0: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE9EF0: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE9EF0: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:141)
==16748==    by 0x4EE9FF8: rclcpp::node_interfaces::NodeBase::~NodeBase() (node_base.cpp:153)
==16748==    by 0x4EE0D77: _M_release (shared_ptr_base.h:154)
==16748==    by 0x4EE0D77: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x4EE0D77: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x4EE0D77: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x4EE0D77: rclcpp::Node::~Node() (node.cpp:195)
==16748==    by 0x110B75: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
==16748==    by 0x10E681: ~__shared_count (shared_ptr_base.h:684)
==16748==    by 0x10E681: ~__shared_ptr (shared_ptr_base.h:1123)
==16748==    by 0x10E681: ~shared_ptr (shared_ptr.h:93)
==16748==    by 0x10E681: main (talker.cpp:98)
==16748==  Block was alloc'd at
==16748==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16748==    by 0x925BCEF: rmw_create_guard_condition (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x92588A1: rmw_create_node (in /opt/workspace/install/lib/librmw_cyclonedds_cpp.so)
==16748==    by 0x51965CC: rcl_node_init (node.c:321)
==16748==    by 0x4EEA3C1: rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool) (node_base.cpp:66)
==16748==    by 0x4EE3D0D: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:116)
==16748==    by 0x4EE58F0: rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&) (node.cpp:103)
==16748==    by 0x112AEE: Talker::Talker(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (talker.cpp:43)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:136)
==16748==    by 0x1136ED: construct<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:475)
==16748==    by 0x1136ED: _Sp_counted_ptr_inplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:526)
==16748==    by 0x1136ED: __shared_count<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr_base.h:637)
==16748==    by 0x1136ED: std::__shared_ptr<Talker, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(std::_Sp_make_shared_tag, std::allocator<Talker> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (shared_ptr_base.h:1295)
==16748==    by 0x10E5CB: shared_ptr<std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:344)
==16748==    by 0x10E5CB: allocate_shared<Talker, std::allocator<Talker>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:691)
==16748==    by 0x10E5CB: make_shared<Talker, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (shared_ptr.h:707)
==16748==    by 0x10E5CB: main (talker.cpp:98)
==16748== 
==16748== 
==16748== HEAP SUMMARY:
==16748==     in use at exit: 3,337,702 bytes in 846 blocks
==16748==   total heap usage: 3,493 allocs, 2,647 frees, 4,102,839 bytes allocated
==16748== 
==16748== LEAK SUMMARY:
==16748==    definitely lost: 736 bytes in 22 blocks
==16748==    indirectly lost: 1,033 bytes in 28 blocks
==16748==      possibly lost: 20,830 bytes in 22 blocks
==16748==    still reachable: 3,315,103 bytes in 774 blocks
==16748==         suppressed: 0 bytes in 0 blocks
==16748== Rerun with --leak-check=full to see details of leaked memory
==16748== 
==16748== For counts of detected and suppressed errors, rerun with: -v
==16748== Use --track-origins=yes to see where uninitialised values come from
==16748== ERROR SUMMARY: 7 errors from 4 contexts (suppressed: 0 from 0)
root@ub80c134adc2254:/opt/workspace# 

Accidental dependency on FastRTPS

I think this created a build mess in rmw_cyclonedds by introducing a dependency on FastRTPS.

colcon graph --packages-up-to rmw_cyclonedds_cpp --packages-above fastrtps   
fastrtps                         +**.......
rosidl_typesupport_fastrtps_cpp   +*..***..
rosidl_typesupport_fastrtps_c      +*..**..
rosidl_typesupport_c                +****..
rosidl_generator_py                  + **..
rosidl_typesupport_cpp                +**..
rosidl_default_generators              + * 
rosidl_default_runtime                  +*.
rmw_dds_common                           +*
rmw_cyclonedds_cpp                        +

Originally posted by @rotu in #145 (comment)

Build failed on ros2 dashing release

Bug report

Build failed on ros2 dashing release.
The code was download yesterday.
Build command is "colcon build --symlink-install"

~/ros2/rmw_cyclonedds/rmw_cyclonedds_cpp/src/rmw_get_topic_endpoint_info.cpp:16:10: fatal error: rmw/get_topic_endpoint_info.h: No such file or directory
#include "rmw/get_topic_endpoint_info.h"

This repo rmw_cyclonedds is set to master branch in ros2.repos file.
And the header get_topic_endpoint_info.h is only on master branch and added in 16 days ago.
This header file is in rmw repo. In dashing release, the rmw is on dashing branch.

Please help to confirm it. If you think it's real issue. Please help correct your ros2.repos file, and share patch file to us. Thanks a lot.

Required Info:

  • Operating System:

Ubuntu 18.04

  • Installation type:

from source

  • Version or commit hash:
  • DDS implementation:
  • Client library (if applicable):

Steps to reproduce issue


Expected behavior

Actual behavior

Additional information


Feature request

Feature description

Implementation considerations

Failures on Windows

Bug report

Required Info:

Steps to reproduce issue

Run the talker listener demo on Windows.

Terminal 1:

set RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 run demo_nodes_cpp talker

Terminal 2:

set RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 run demo_nodes_cpp listener

demo_nodes_py can be also used.

Expected behavior

It should work.

Actual behavior

It doesn't work.

Additional information

Several test failed in CI on Windows:
https://ci.ros2.org/view/nightly/job/nightly_win_extra_rmw_rel/543/#showFailuresLink

After 543, all other runs of that job failed or were aborted.
I've been able to reproduce some of those test failures locally.

Fun fact:
If combine one talker/listener from rmw_fastrtps_cpp and the other from rmw_cyclonedds_cpp, it works. But if both of them are using rmw_cyclonedds_cpp, it doesn't (which I find super strange).

Memory leak when unloading a component offering a service under Cyclone DDS

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • Binaries
  • Version or commit hash:
    • Eloquent
  • DDS implementation:
    • Cyclone DDS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

  1. Have a node that offers a service, built as component
  2. Load component
  3. Call service
  4. Unload component

Expected behavior

Node is unloaded, memory is freed.

Actual behavior

Error message [ERROR] [rclcpp]: Error in destruction of rcl service handle: the Node Handle was destructed too early. You will leak memory

Additional information

I have multiple identical nodes loaded as components, unloading them all at once. The error occurs only rarely, but if it does, it will occur for a large number of nodes at once.

Events still need to be implemented

Bug report

Required Info:

  • Operating System:
  • Installation type:
  • Version or commit hash:
  • DDS implementation:
  • Client library (if applicable):

Steps to reproduce issue


Expected behavior

Actual behavior

Additional information


Feature request

Feature description

Implementation considerations

Action-server fails (with an action-client to self)

Bug report

Required Info:

  • Operating System: Ubuntu 18.04
  • Installation type: source
  • Version or commit hash: 1205ab5
  • DDS implementation: CycloneDDS 😄
  • Client library (if applicable): rclcpp

Steps to reproduce issue

  • Build this modified example of the rclcpp minimal action server example.
  • Run it:
    ros2 run examples_rclcpp_minimal_action_server action_server_member_functions
  • Send an action request through the terminal:
    ros2 action send_goal /fibonacci example_interfaces/action/Fibonacci '{order: 10}'

Expected behavior

Action server receives the request and starts sending feedback:

[INFO] [minimal_action_server]: Received goal request with order 10
[INFO] [minimal_action_server]: Executing goal
[INFO] [minimal_action_server]: Publish Feedback
[INFO] [minimal_action_server]: Publish Feedback
...

Actual behavior

Node crashes:

[INFO] [minimal_action_server]: Received goal request with order 10
terminate called after throwing an instance of 'rclcpp::exceptions::RCLError'
  what():  error taking goal response: error not set
[INFO] [minimal_action_server]: Executing goal

Additional information

As you inspect the code you'll notice something a bit unorthodox: we have an action-server created on MinimalActionServer and an action-client on an internal node, both actions have the same type and name. Also, nodes are spinning on separate executors.

The idea behind this is that the user has the option to request the execution of an action by publishing a /trigger message. This is a simplified version of something we're doing in ros2/nav2.

As mentioned above, if the user sends the request through the action interface the node crashes. However if the user sends the request as a message:

ros2 topic pub /trigger std_msgs/Empty

it is successfully processed 🤔

deserializer doesn't do byte swapping

The custom serializer/deserializer that converts between ROS message format and CDR (a derivative of the dynamic FastRTPS RMW layer) doesn't do any form of checking or byteswapping of its input in a mixed-endian network.

Incompatible with Crystal

I'm using a source installation of ROS2 from tip of master on Ubuntu Bionic.
Built CycloneDDS, exported CycloneDDS_DIR=<install-dir>/share/CycloneDDS and appended LD_LIBRARY_PATH with <install-dir>/lib.
Cloned this repo into the src/ros2/ dir, and ran colcon build --symlink-install --cmake-force-configure which failed.

First error was rmw_cyclonedds_cpp/TypeSupport_impl.hpp trying to include a non existing file - "rosidl_generator_c/primitives_array_functions.h", which has been renamed to "rosidl_generator_c/primitives_sequence_functions.h" in crystal. After fixing that there were a ton of other issues though.

CycloneDDS can hang on node destruction

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • Source
  • Version or commit hash:
    • Master
  • DDS implementation:
    • rmw_cyclonedds_cpp
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

Very occasionally, tests in test_tf2 fail with timeouts

colcon test --packages-select test_tf2

This does not happen every time, and having ros2 bag record -a running seems to make it more likely.

Expected behavior

The test suite succeeds.

Actual behavior

The test suite fails with a timeout in some test or another. Decorating the test suite with debug statements indicates that the failure is some sort of hang in the destructor of rclcpp::Node.

Additional information

GDB backtrace:

#0  0x00007ffbafe089f3 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0xe445a4) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0xe44550, cond=0xe44578) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0xe44578, mutex=0xe44550) at pthread_cond_wait.c:655
#3  0x00007ffbac999166 in ddsrt_cond_wait (cond=0xe445a4, mutex=0x80) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/ddsrt/src/sync/posix/sync.c:92
#4  0x00007ffbac95e0fb in gcreq_queue_drain (q=0xe44540) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsi/src/q_gc.c:217
#5  0x00007ffbac9612e9 in rtps_stop (gv=0xdf32b0) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsi/src/q_init.c:1673
#6  0x00007ffbac981fc7 in dds_domain_free (vdomain=0xdf3010) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_domain.c:263
#7  0x00007ffbac984f94 in dds_entity_deriver_delete (e=0xdf3010) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds__types.h:189
#8  really_delete_pinned_closed_locked (e=0xdf3010, delstate=DIS_EXPLICIT) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_entity.c:503
#9  0x00007ffbac984bd0 in dds_delete_impl_pinned (e=0xdf3010, delstate=DIS_EXPLICIT) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_entity.c:400
#10 dds_delete_impl (entity=<optimized out>, delstate=DIS_EXPLICIT) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_entity.c:375
#11 dds_delete (entity=<optimized out>) at /opt/ros/master/src/eclipse-cyclonedds/cyclonedds/src/core/ddsc/src/dds_entity.c:358
#12 0x00007ffbacbe07c3 in node_gone_from_domain_locked (did=42) at /opt/ros/master/src/ros2/rmw_cyclonedds/rmw_cyclonedds_cpp/src/rmw_node.cpp:568
#13 rmw_destroy_node (node=<optimized out>) at /opt/ros/master/src/ros2/rmw_cyclonedds/rmw_cyclonedds_cpp/src/rmw_node.cpp:833
#14 0x00007ffbb97b9d8c in rcl_node_fini (node=0xe45400) at /opt/ros/master/src/ros2/rcl/rcl/src/rcl/node.c:457
#15 0x00007ffbb9a8fd66 in rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::$_1::operator()(rcl_node_t*) const (this=<optimized out>, node=0xe45400) at /opt/ros/master/src/ros2/rclcpp/rclcpp/src/rclcpp/node_interfaces/node_base.cpp:125
#16 0x00007ffbb9a8fe7a in std::_Sp_counted_deleter<rcl_node_t*, rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::$_1, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (this=<optimized out>) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:470
#17 0x00007ffbb9a8f712 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=warning: RTTI symbol not found for class 'std::_Sp_counted_deleter<rcl_node_t*, rclcpp::node_interfaces::NodeBase::NodeBase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<rclcpp::Context>, rcl_node_options_t const&, bool)::$_1, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>'
0xe45000) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:154
#18 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7ffb94002008) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:684
#19 std::__shared_ptr<rcl_node_t, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7ffb94002000) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:1123
#20 rclcpp::node_interfaces::NodeBase::~NodeBase (this=0x7ffb94001fe0) at /opt/ros/master/src/ros2/rclcpp/rclcpp/src/rclcpp/node_interfaces/node_base.cpp:153
#21 0x00007ffbb9a8f8a9 in rclcpp::node_interfaces::NodeBase::~NodeBase (this=0x7ffb94001fe0) at /opt/ros/master/src/ros2/rclcpp/rclcpp/src/rclcpp/node_interfaces/node_base.cpp:142
#22 0x00007ffbb9a8a1ed in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=warning: RTTI symbol not found for class 'std::_Sp_counted_ptr<rclcpp::node_interfaces::NodeBase*, (__gnu_cxx::_Lock_policy)2>'
0xe45060) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:154
#23 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0xdf05d0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:684
#24 std::__shared_ptr<rclcpp::node_interfaces::NodeBaseInterface, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0xdf05c8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:1123
#25 rclcpp::Node::~Node (this=0xdf05b0) at /opt/ros/master/src/ros2/rclcpp/rclcpp/src/rclcpp/node.cpp:186
#26 0x000000000040a947 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=warning: RTTI symbol not found for class 'std::_Sp_counted_ptr_inplace<rclcpp::Node, std::allocator<rclcpp::Node>, (__gnu_cxx::_Lock_policy)2>'
0xdf05a0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:154
#27 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7fffaa5f4ee0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:684
#28 std::__shared_ptr<rclcpp::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7fffaa5f4ed8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:1123
#29 MessageFilter_noTransformsSameFrame_Test::TestBody (this=<optimized out>) at /opt/ros/master/src/ros2/geometry2/test_tf2/test/test_message_filter.cpp:108
#30 0x0000000000444fa4 in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void> (object=<optimized out>, method=<optimized out>, location=0x452b64 "the test body") at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2447
#31 testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void> (object=<optimized out>, method=<optimized out>, location=0x452b64 "the test body") at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2483
#32 0x0000000000425008 in testing::Test::Run (this=0xe53fa0) at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2522
#33 0x0000000000426150 in testing::TestInfo::Run (this=0xda8e80) at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2703
#34 0x0000000000426897 in testing::TestCase::Run (this=0xdedc20) at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2825
#35 0x0000000000433217 in testing::internal::UnitTestImpl::RunAllTests (this=<optimized out>) at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:5216
#36 0x0000000000445b44 in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=<optimized out>, method=<optimized out>, location=0x45331f "auxiliary test code (environments or event listeners)") at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2447
#37 testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=<optimized out>, method=<optimized out>, location=0x45331f "auxiliary test code (environments or event listeners)") at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:2483
#38 0x0000000000432e8c in testing::UnitTest::Run (this=0x665a98 <testing::UnitTest::GetInstance()::instance>) at /opt/ros/master/install/src/gtest_vendor/./src/gtest.cc:4824
#39 0x0000000000410590 in RUN_ALL_TESTS () at /opt/ros/master/install/src/gtest_vendor/include/gtest/gtest.h:2370
#40 main (argc=1, argc@entry=2, argv=argv@entry=0x7fffaa5f57f8) at /opt/ros/master/src/ros2/geometry2/test_tf2/test/test_message_filter.cpp:409
#41 0x00007ffbafa2bb97 in __libc_start_main (main=0x410510 <main(int, char**)>, argc=2, argv=0x7fffaa5f57f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffaa5f57e8) at ../csu/libc-start.c:310
#42 0x00000000004093aa in _start () at /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/basic_string.h:220

rosdep can not resolve 'cyclonedds' dependency key

This currently breaks the ROS2 night docker image build. Could we ensure all keys in the package XML are resolvable from ros-distro?

<build_depend>cyclonedds</build_depend>

Reading package lists...
ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
rmw_cyclonedds_cpp: Cannot locate rosdep definition for [cyclonedds]
Removing intermediate container a9fb7f22755c

Disconnect entities when they are using intra-process communication

A relevant problem of ROS2 is that it wastes resources when you have both inter and intra-process communication enabled.

For example:

  • Process 1: Node A publishes on my_topic, Node B subscribes on my_topic. They use intra-process communication.
  • Process 2: Node C subscribes on my_topic.

In this configuration Node A is publishing both inter and intra-process.
The RMW is not aware of the existence of Intra-process communication, so, every message published inter-process is delivered to both nodes.
Currently the subscription in Node B would discard the inter-process message received from Node A (since they are in the same intra-process context). However, this is done at the rclcpp layer, after the message has been sent and deserialized.

Is there a plan for implementing a feature for "disconnecting" entities that are already using intra-process communication?

Does CycloneDDS already provide functions for disconnecting a pair of entities without deleting them?

Thank you

MSBuild warnings in serdata.cpp

Bug report

Required Info:
Building on Windows 10, 1903 in a docker container with the latest VCTools (16.24) installed from VS BuildTools.
https://citest.ros2.org/job/nightly_win_extra_rmw_rel/10/warnings43Result/

I get a couple of MSBuild warnings,
serdata.cpp:115

'initializing': conversion from 'size_t' to 'uint32_t', possible loss of data

Looks to be introduced in #77

serdata.cpp:506

unary minus operator applied to unsigned type, result still unsigned

Introduced in #75

@rotu

update readme to include apt install option

please update readme to 1st show "How to" with apt install before showing how to build it

How to use

  1. Install:
    apt install ros-eloquent-rmw-cyclonedds-cpp
    (or dashing)
  2. Set env variable and run as usual
    RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
  3. Confirm RMW: In Eloquent, to confirm which RMW you're using
    ros2 doctor --report

Confusion over versioning

Unlike most other ROS2 repos, rmw_cyclonedds shares a codebase between different ROS major versions. This causes frequent breakages when someone makes, e.g. a fix for Foxy that breaks Eloquent due to a changed header.

We need to make it more obvious which branch is for which release and prevent these breakages.

Windows 10 Compilation Fails

Bug report

Required Info:

  • Operating System:
    • Windows 10
  • Installation type:
    • source
  • Version or commit hash:
    • master
  • DDS implementation:
    • rmw_cyclonedds
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Try to build on Windows 10 with Cyclone DDS installed.

Expected behavior

Successful compilation and the ability to be used in runtime.

Actual behavior

Compilation fails


Note: I'm working on some patches for you, I'll file them tonight.

One issue is with __attribute__ ((unused)) which isn't supported on Windows 10. Since the CMakeLists.txt file specifies C++14, I've changed these instances to static_cast<void>(var). In C++17, one could use [[maybe unused]], but I'm only noting this for completeness.

I'll see if I can figure out what else is blocking the windows compilation as well, but that might take me a bit longer ;).

Glad to see a new middleware appear! Pretty exciting stuff!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.