-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Panic occurs when publish sequence types for Rust 1.78 #406
Comments
Why do you use a deprecated Message type? What else did you want to achieve with your publisher? |
@Guelakais As I mentioned in the text, this issue occurs with messages that use sequence types, such as sensor_msgs::msg::PointCloud2 or sensor_msgs::msg::Joy. They include array types, such as I developed a publisher for sensor_msgs::msg::PointCloud2 and added an example of it below. sourceuse rclrs::{Context, Node};
use sensor_msgs::msg::PointCloud2;
use sensor_msgs::msg::PointField;
fn main() {
let context = Context::new([]).expect("failed to create node");
let node =
Node::new(&context, "rust_ros2_pointcloud_publisher").expect("failed to create node");
let publisher = node
.create_publisher::<PointCloud2>("pointcloud", rclrs::QOS_PROFILE_DEFAULT)
.expect("failed to create publisher");
let duration_since_epoch = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap();
let header = std_msgs::msg::Header {
stamp: builtin_interfaces::msg::Time {
sec: duration_since_epoch.as_secs() as i32,
nanosec: duration_since_epoch.subsec_nanos(),
},
frame_id: "map".to_string(),
};
// for test
let data = vec![
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (0, 0, 0)
0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, // (1.0, 1.0, 1.0)
0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, // (2.0, 2.0, 2.0)
];
let pointcloud = PointCloud2 {
header: header,
height: 1,
width: 3,
fields: vec![
PointField {
name: "x".to_string(),
offset: 0,
datatype: PointField::FLOAT32,
count: 1,
},
PointField {
name: "y".to_string(),
offset: 4,
datatype: PointField::FLOAT32,
count: 1,
},
PointField {
name: "z".to_string(),
offset: 8,
datatype: PointField::FLOAT32,
count: 1,
},
],
is_bigendian: false,
point_step: 12,
row_step: 36,
data: data,
is_dense: true,
};
publisher
.publish(pointcloud)
.expect("failed to publish message");
println!("Published PointCloud2 message");
} panic message$ cargo run --bin pointcloud
Compiling hello_world v0.1.0 (/home/oscarchoi/Workspace/rclrs-tutorial/hello_world)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.33s
Running `target/debug/pointcloud`
thread 'main' panicked at library/core/src/panicking.rs:156:5:
unsafe precondition(s) violated: ptr::write_bytes requires that the destination pointer is aligned and non-null
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
Aborted (core dumped) |
Thanks for reporting this @Oscarchoi . I think we should start by using the In the best case scenario we would have a test that runs two processes and sends every test message type from one process to the other. |
@mxgrey Thanks! That would be very helpful. If there are any issues or plans that arise later, I'd like to help as well :) And if you confirm that the changes I made are appropriate, I'll be happy to submit a PR for the fix. |
Thank you for the detailed explanation. ros2 rust is a ros2 interface written in rust and I'm not sure with many bugs if they are generated by rust or directly by ros2. In this case it seems to be clear. I'll play around with it a bit soon. If you are generally interested in what you can do with ros2 rust, I can recommend a few sources: |
You can feel free to submit the PR as-is. Part of the PR process is determining if changes are appropriate or not. At first glance, though, things look fine to me, though a few extra pairs of eyes on the code would be appreciated. There might be some sort of possible consequence that I haven't considered, after all. In any case, thank you not only for the report but for also looking into this! It's much appreciated! |
Thank you for the advice! I will use it as a reference for utilizing rust_ros2 :)
Thank you for reviewing it. And I'm glad to hear that it was helpful :) |
I found that, in Rust 1.78, when trying to publish data of sequence types, such as std_msgs::msg::UInt8MultiArray or messages utilizing sensor_msgs::msg::PointCloud2, a panic occurs with the message:
unsafe precondition(s) violated: ptr::write_bytes requires that the destination pointer is aligned and non-null.
I tested
ros2-rust 0.4.1
on ubuntu 22.04.1 + ros2 humble and checked on ubuntu 20.04.6 + ros2 foxy, too.The source code I tested and the backtrace message are as follows:
source
backtrace
It seems that the panic arises at the following location:
ros2_rust/rosidl_runtime_rs/src/sequence.rs
Lines 510 to 515 in ede2291
In the current implementation, if the size is 0 (which happens when initialization), it's expected that
seq.data
will be null. However, according to the latest std documentation (https://doc.rust-lang.org/nightly/std/ptr/fn.write_bytes.html), even if the number of bytes being written is 0, the pointer should not be null. I believe this is causing the panic.It seems that a null pointer is inevitable when the size is 0, due to the implementation of rosidl_runtime (https://github.com/ros2/rosidl/blob/4ba0effa201030ae8f45597b29d4ca685b2d50a1/rosidl_runtime_c/src/primitives_sequence_functions.c#L24-L43).
I'm quite new to rust and not sure what the correct solution is, I found that adding a null check before the write_bytes prevents the panic and makes the publish work. Oscarchoi@8b1e786
The text was updated successfully, but these errors were encountered: