Skip to content

feat(tracing): emit the tracetools rmw_* tracepoints for ros2_tracing - #74

Open
benaliabderrahmane wants to merge 2 commits into
develfrom
feature/tracetools-tracepoints
Open

benaliabderrahmane wants to merge 2 commits into
develfrom
feature/tracetools-tracepoints

Conversation

@benaliabderrahmane

Copy link
Copy Markdown
Owner

Description

Adds the four rmw-level tracepoints that ros2_tracing defines for an RMW — rmw_publisher_init, rmw_subscription_init, rmw_publish, rmw_take — mirroring rmw_cyclonedds and rmw_fastrtps. With them, the standard tracing stack (ros2 trace, tracetools_analysis, Trace Compass ROS 2 incubator, CARET) follows a message across processes on this RMW instead of stopping at the process boundary.

How the cross-process link works. ros2_tracing pairs rmw_publish.timestamp in the publishing process with rmw_take.source_timestamp in the receiving one by int64 equality. Both sides pass WireHeader::source_timestamp_ns, the stamp already on the wire, so no wire-format change and no new state.

What changed (20 lines, 4 files):

  • package.xml / CMakeLists.txt: depend on and link tracetools (PRIVATE; it is already a transitive dependency of rcl, so nothing new gets installed).
  • rmw_publisher.cpp: rmw_publisher_init at creation; rmw_publish in rmw_publish and rmw_publish_serialized_message, right after the header stamp is set.
  • rmw_subscription.cpp: rmw_subscription_init at creation; rmw_take on the successful-take path of all five take variants (rmw_take_sequence fires once per message). The analyses only consume taken = 1 events, so the empty-queue return does not emit.
  • README.md: one row in the design table (separate commit, drop it if unwanted).

On the sketch in #31. No TRACETOOLS_ENABLED guard is needed: TRACETOOLS_TRACEPOINT already expands to nothing when tracetools was built with tracing disabled. There is no rmw-level wait tracepoint in tracetools (waiting is covered by the rcl/rclcpp executor events), so nothing to emit there. Jazzy's tracetools has no request/response rmw tracepoints either, so a client → service hop across processes is still not linked by the analyses; that is an upstream gap, not something this RMW can fill.

Fixes #31

Is this user-facing behavior change?

Additive. ros2 trace sessions now record rmw_* events from this RMW, and message-flow analyses work end to end. With no tracing session active, each call site costs one predicted-not-taken branch, the same as in the DDS RMWs.

How was this tested?

Jazzy, host build (RelWithDebInfo).

  • test_rmw_pub_sub and test_rmw_cross_process pass.
  • nm -D on the built .so shows the four ros_trace_rmw_* imports; ldd shows libtracetools.so and liblttng-ust.so.1.
  • Live LTTng session (lttng enable-event -u 'ros2:*') over demo_nodes_cpp talker + listener with RMW_IMPLEMENTATION=rmw_unix_socket_cpp, both nodes started after the session. Recorded 513 rmw_publish and 187 rmw_take events alongside the full rclcpp chain (callback_start/end, rclcpp_publish, rcl_take). All 177 distinct rmw_take.source_timestamp values matched an rmw_publish.timestamp, i.e. every taken message links back to its publish:
ros2:rmw_publish: { rmw_publisher_handle = 0x609A6BB7CAA0, message = 0x7FFE8AD3A040, timestamp = 1790066885220209681 }
ros2:rmw_take:    { rmw_subscription_handle = 0x62FC1F962750, message = 0x62FC1F96DB90, source_timestamp = 1790066885220566706, taken = 1 }

Did you use Generative AI?

Yes. Claude Code (Claude Fable 5.1) drafted the change, the LTTng verification scripts and this description.

Additional Information

Usage: ros2 trace start <session> before launching the nodes (callback names and topic names come from init-time events), run the scenario, ros2 trace stop <session>, then ros2 trace-analysis process ~/.ros/tracing/<session> for a per-callback summary or open the trace in Trace Compass (ROS 2 Message Flow view) to follow one message across nodes.

Add rmw_publisher_init, rmw_subscription_init, rmw_publish and rmw_take
tracepoints, mirroring rmw_cyclonedds/rmw_fastrtps. ros2_tracing links a
publish to its take across processes by rmw_publish.timestamp ==
rmw_take.source_timestamp; both sides pass WireHeader.source_timestamp_ns,
so Trace Compass / CARET message-flow analysis now follows a message through
UDS-connected nodes instead of stopping at the process boundary.

Verified with an LTTng session over demo_nodes_cpp talker/listener under
RMW_IMPLEMENTATION=rmw_unix_socket_cpp: 177/177 taken messages matched a
publish event by timestamp; test_rmw_pub_sub and test_rmw_cross_process pass.
@benaliabderrahmane

Copy link
Copy Markdown
Owner Author

CI note: the lyrical failure is the distro image, not this PR.

build & test (lyrical) fails at test time with

symbol lookup error: /opt/ros/lyrical/lib/libtest_msgs__rosidl_typesupport_fastrtps_c.so:
undefined symbol: has_buffer_fields_builtin_interfaces__msg__Duration

Every test that links test_msgs (8 binaries) dies on load; the library itself builds fine. The symbol belongs to the rosidl_buffer / has_buffer_fields generator change, so ros:lyrical-ros-base currently ships a test_msgs typesupport built against a newer builtin_interfaces than the one installed — the same class of skew the workflow already patches around for rolling.

Evidence it predates this branch: a workflow_dispatch control run on plain devel (04d16f2) fails identically, lyrical only, same symbol, jazzy/kilted/rolling green: https://github.com/benaliabderrahmane/rmw_unix_socket_cpp/actions/runs/35708815784. All four distros were green on 2026-09-18 (#65#71), so the image drifted since then.

Also: GitHub only auto-links/auto-closes Fixes #31 for PRs against the default branch, so #31 needs a manual close when this lands (or when devel is merged into main).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant