RoboStack / RoboStack/ros-lyrical
robostack-lyrical ships rosidl_runtime_c (5.2.1) with rosidl_buffer-extended primitive sequences, but Rust bindings use the 24-byte layout → rclrs nodes corrupt/segfault on primitive-sequence messages
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 11
- Forks
- 13
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 8
Description
Solution to issue cannot be found in the documentation.
- I checked the documentation.
Issue
Summary
ros-lyrical-rosidl-runtime-c 5.2.1 defines primitive sequences with the rosidl_buffer extension (is_rosidl_buffer/owns_rosidl_buffer → 32-byte struct), but the Rust bindings used in the same channel (ros-lyrical-rosidl-generator-rs 5.2.1 + rosidl_runtime_rs 0.6.0) use the standard 24-byte Sequence<T>. The C and Rust ABIs therefore disagree for every primitive-sequence field, so any rclrs node silently corrupts or segfaults on such messages.
Environment
robostack-lyrical (linux-64); ros-lyrical-rosidl-runtime-c 5.2.1 (build np2py314…_22), ros-lyrical-rosidl-generator-rs 5.2.1; rosidl_runtime_rs 0.6.0; rclrs 0.7; rustc 1.97.0, edition 2024.
Root cause
This channel's primitives_sequence.h gives primitive sequences two extra trailing fields:
<T>* data; size_t size; size_t capacity; // 0 / 8 / 16
bool is_rosidl_buffer; bool owns_rosidl_buffer; // 24 / 25 -> struct padded to 32
rosidl_runtime_rs::Sequence<T> is the standard 24-byte, 3-field struct for all T.
| C type | C size | Rust Sequence<T> |
|---|---|---|
uint8__Sequence / double__Sequence (primitive) |
32 | 24 |
Point__Sequence / ColorRGBA__Sequence (message) |
24 | 24 |
Measured (gcc sizeof/offsetof on the installed headers vs Rust size_of/offset_of): primitive sequences 32 vs 24; visualization_msgs/Marker C sizeof 480 vs Rust 464, agreeing through texture (offset 256) then shifting +8 at uv_coordinates/text/mesh_resource — introduced by the primitive CompressedImage.data sequence (C CompressedImage 88 vs Rust 80).
Symptom
Marker::default() round-trips via from_rmw_message, .to_string()-ing text at the shifted offset:
debug: panic: slice::from_raw_parts requires the pointer to be aligned and non-null
release: SIGSEGV (invalid memory reference)
<String as Display>::fmt rosidl_runtime_rs-0.6.0/src/string.rs:187
Marker::from_rmw_message visualization_msgs/rust/src/msg.rs:1133 (field: text)
Marker::default visualization_msgs/rust/src/msg.rs:1035
Same corruption for any primitive sequence with fields after it — sensor_msgs/JointState (velocity/effort), trajectory_msgs/JointTrajectoryPoint (positions). Benign only when the misread lands on zeroed empty-default memory.
Upstream comparison
ros2/rosidl master primitives_sequence.h has only data/size/capacity, so this is specific to packages built with the rosidl_buffer extension in this channel.
Ask
Is the Rust binding set in robostack-lyrical expected to be ABI-consistent with these rosidl_buffer-extended C sequences? If so, the shipped Rust runtime/generator needs to model the 32-byte primitive layout; if the extension is unintended for this channel, the C packages need rebuilding without it.
Upstream Rust tracking: https://github.com/ros2-rust/ros2_rust/issues/659
Installed packages
$ pixi list --explicit
Installed for: linux-64
Name Version Build Size Kind Source
ccache 4.13.6 hedf47ba_0 835.64 KiB conda https://prefix.dev/conda-forge
clangdev 22.1.8 default_h1b9a2e9_3 59.08 MiB conda https://prefix.dev/conda-forge
cmake 4.4.0 hc85cc9f_0 22.56 MiB conda https://prefix.dev/conda-forge
colcon-common-extensions 0.3.0 py314hdafbbf9_4 12.82 KiB conda https://prefix.dev/conda-forge
colcon-mixin 0.2.3 pyhd8ed1ab_1 24.56 KiB conda https://prefix.dev/conda-forge
colcon_cargo 0.2.0 pypi https://pypi.org/simple
colcon_ros_cargo 0.2.0 pypi https://pypi.org/simple
compilers 1.11.0 ha770c72_0 7.31 KiB conda https://prefix.dev/conda-forge
curl 8.21.0 hae6b9f4_2 190.21 KiB conda https://prefix.dev/conda-forge
filelock 3.29.7 pyhd8ed1ab_0 38.72 KiB conda https://prefix.dev/conda-forge
libcurl 8.21.0 hae6b9f4_2 469.07 KiB conda https://prefix.dev/conda-forge
lld 22.1.8 hef48ded_0 11.84 MiB conda https://prefix.dev/conda-forge
ninja 1.13.2 h171cf75_0 181.96 KiB conda https://prefix.dev/conda-forge
patch 2.8 hb03c661_1002 114.47 KiB conda https://prefix.dev/conda-forge
pkg-config 0.29.2 h4bc722e_1009 112.48 KiB conda https://prefix.dev/conda-forge
python 3.14.6 habeac84_100_cp314 35.02 MiB conda https://prefix.dev/conda-forge
ros-lyrical-rmw-zenoh-cpp 0.10.4 np2py314h19ba983_22 350.58 KiB conda https://prefix.dev/robostack-lyrical
ros-lyrical-ros-base 0.13.0 np2py314hb48eaa3_22 21.67 KiB conda https://prefix.dev/robostack-lyrical
ros-lyrical-rosidl-generator-rs 0.4.12 np2py314hb48eaa3_22 47.02 KiB conda https://prefix.dev/robostack-lyrical
rust 1.97.0 h53717f1_0 165.58 MiB conda https://prefix.dev/conda-forge
vcstool 1.1.7 hd8ed1ab_0 10.24 KiB conda https://prefix.dev/conda-forge
Environment info
System
------------
Pixi version: 0.73.0
TLS backend: rustls
Platform: linux-64
Virtual packages: __unix=0=0
: __linux=7.0.2=0
: __glibc=2.41=0
: __archspec=1=x86_64_v4
Cache dir: /root/.cache/rattler/cache
Auth storage: /root/.rattler/credentials.json
Config locations: No config files found
Global
------------
Bin dir: /root/.pixi/bin
Environment dir: /root/.pixi/envs
Manifest dir: /root/.pixi/manifests/pixi-global.toml
Workspace
------------
Name: eit_robot
Version: 1.0.0
Manifest file: /root/eit/eit_robot/pixi.toml
Last updated: 21-07-2026 11:36:59
Environments
------------
Environment: default
Features: linux, default
Channels: https://prefix.dev/pixi-build-backends, https://prefix.dev/conda-forge, https://prefix.dev/robostack-lyrical
Dependency count: 19
Dependencies: python, rust, ros-lyrical-ros-base, ros-lyrical-rmw-zenoh-cpp, ros-lyrical-rosidl-generator-rs, colcon-common-extensions, colcon-mixin, compilers, cmake, ninja, pkg-config, libcurl, filelock, ccache, lld, curl, clangdev, patch, vcstool
PyPI Dependencies: colcon-cargo, colcon-ros-cargo
Target platforms: linux-aarch64, linux-64
Resolved platform: linux-64 (archspec=x86_64, glibc=2.28, linux=4.18, __unix)
Minimum platform: linux-64 (glibc=2.28, __unix)
Prefix location: /root/eit/eit_robot/.pixi/envs/default
Tasks: colcon_mixin_setup, update_deps, build_clean, test_teleop, test_capture_kinematics, clean, pytests, test, test_capture_solver, setup, test_teleop_pure, test_capture_executor, test_control, setup_ros_rust, test_capture_interfaces, build
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Compare the installed rosidl_runtime_c/include/rosidl_runtime_c/primitives_sequence.h layout with rosidl_runtime_rs 0.6.0's Sequence, then reproduce the Marker::default/from_rmw_message failure in visualization_msgs/rust/src/msg.rs. Check rosidl_runtime_rs-0.6.0/src/string.rs at the reported panic and verify that primitive-sequence fields no longer shift later fields or corrupt messages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, rust
- Domain
- robotics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100