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.
This commit is contained in:
LIYOU ZHOU 2023-03-21 07:55:45 +00:00 committed by GitHub
parent 0ed365f598
commit 88c16ba598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 4 deletions

View File

@ -1,3 +1,4 @@
use std::ffi::CStr;
use std::ffi::CString; use std::ffi::CString;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@ -13,6 +14,19 @@ pub struct Context {
pub(crate) context_handle: Arc<Mutex<ContextHandle>>, pub(crate) context_handle: Arc<Mutex<ContextHandle>>,
} }
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 {} unsafe impl Send for Context {}
impl Context { impl Context {
@ -32,14 +46,14 @@ impl Context {
let is_valid = unsafe { let is_valid = unsafe {
let allocator = rcutils_get_default_allocator(); let allocator = rcutils_get_default_allocator();
let mut init_options = rcl_get_zero_initialized_init_options(); let mut init_options = rcl_get_zero_initialized_init_options();
rcl_init_options_init(&mut init_options, allocator); check_rcl_ret!(rcl_init_options_init(&mut init_options, allocator));
rcl_init( check_rcl_ret!(rcl_init(
(c_args.len() - 1) as ::std::os::raw::c_int, (c_args.len() - 1) as ::std::os::raw::c_int,
c_args.as_ptr(), c_args.as_ptr(),
&init_options, &init_options,
ctx.as_mut(), 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()) rcl_context_is_valid(ctx.as_mut())
}; };