From 88c16ba598ec43f245f28d09f63ad6439d685441 Mon Sep 17 00:00:00 2001 From: LIYOU ZHOU Date: Tue, 21 Mar 2023 07:55:45 +0000 Subject: [PATCH] Add return value checking when invoking c APIs (#41) During rcl_init, things could fail and result in segfault. In this patch, we check the return code of c function calls and panic in case of error. --- r2r/src/context.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/r2r/src/context.rs b/r2r/src/context.rs index c33e262..c73c3ab 100644 --- a/r2r/src/context.rs +++ b/r2r/src/context.rs @@ -1,3 +1,4 @@ +use std::ffi::CStr; use std::ffi::CString; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; @@ -13,6 +14,19 @@ pub struct Context { pub(crate) context_handle: Arc>, } +macro_rules! check_rcl_ret { + ($ret:expr) => { + if $ret != RCL_RET_OK as i32 { + let err_str = rcutils_get_error_string(); + // c_char's definition is architecture specific + // https://github.com/fede1024/rust-rdkafka/issues/121#issuecomment-486578947 + let str_ptr = &(err_str.str_) as *const std::os::raw::c_char; + let error_msg = CStr::from_ptr(str_ptr); + panic!("{}", error_msg.to_str().expect("to_str() call failed")); + } + }; +} + unsafe impl Send for Context {} impl Context { @@ -32,14 +46,14 @@ impl Context { let is_valid = unsafe { let allocator = rcutils_get_default_allocator(); let mut init_options = rcl_get_zero_initialized_init_options(); - rcl_init_options_init(&mut init_options, allocator); - rcl_init( + check_rcl_ret!(rcl_init_options_init(&mut init_options, allocator)); + check_rcl_ret!(rcl_init( (c_args.len() - 1) as ::std::os::raw::c_int, c_args.as_ptr(), &init_options, ctx.as_mut(), - ); - rcl_init_options_fini(&mut init_options as *mut _); + )); + check_rcl_ret!(rcl_init_options_fini(&mut init_options as *mut _)); rcl_context_is_valid(ctx.as_mut()) };