Skip to content

Commit 451db14

Browse files
author
Meir Shpilraien (Spielrein)
authored
Added trace to module crash report (#192)
* Added trace to module crash report The trace provided by Redis is not fully compatible to rust. The PR adds a section to the crash report (under the module info section) with the rust trace. * review fixes
1 parent 9bd08b6 commit 451db14

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum-primitive-derive = "^0.1"
5656
num-traits = "^0.2"
5757
strum_macros = "0.22"
5858
#failure = "0.1"
59+
backtrace = "0.3"
5960

6061
[dev-dependencies]
6162
anyhow = "1.0.38"

src/lib.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ pub use crate::context::thread_safe::{DetachedFromClient, ThreadSafeContext};
3030
pub use crate::raw::NotifyEvent;
3131

3232
pub use crate::context::Context;
33-
pub use crate::raw::Status;
33+
pub use crate::raw::*;
3434
pub use crate::redismodule::*;
35+
use backtrace::Backtrace;
3536

3637
/// Ideally this would be `#[cfg(not(test))]`, but that doesn't work:
3738
/// https://github.com/rust-lang/rust/issues/59168#issuecomment-472653680
@@ -59,3 +60,15 @@ fn from_byte_string(byte_str: *const c_char, length: size_t) -> Result<String, U
5960

6061
String::from_utf8(vec_str).map_err(|e| e.utf8_error())
6162
}
63+
64+
pub fn base_info_func(ctx: *mut RedisModuleInfoCtx, for_crash_report: bool) {
65+
if !for_crash_report {
66+
return;
67+
}
68+
// add rust trace into the crash report
69+
if add_info_section(ctx, Some("trace")) == Status::Ok {
70+
let current_backtrace = Backtrace::new();
71+
let trace = format!("{:?}", current_backtrace);
72+
raw::add_info_field_str(ctx, "trace", &trace);
73+
}
74+
}

src/macros.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ macro_rules! redis_module {
109109
]),* $(,)*
110110
])?
111111
) => {
112+
extern "C" fn __info_func(
113+
ctx: *mut $crate::raw::RedisModuleInfoCtx,
114+
for_crash_report: i32,
115+
) {
116+
$crate::base_info_func(ctx, for_crash_report == 1);
117+
}
118+
112119
#[no_mangle]
113120
#[allow(non_snake_case)]
114121
pub extern "C" fn RedisModule_OnLoad(
@@ -168,6 +175,8 @@ macro_rules! redis_module {
168175
)*
169176
)?
170177

178+
raw::register_info_function(ctx, Some(__info_func));
179+
171180
raw::Status::Ok as c_int
172181
}
173182

src/raw.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,40 @@ pub fn subscribe_to_server_event(
571571
unsafe { RedisModule_SubscribeToServerEvent.unwrap()(ctx, event, callback).into() }
572572
}
573573

574+
#[allow(clippy::not_unsafe_ptr_arg_deref)]
575+
pub fn register_info_function(
576+
ctx: *mut RedisModuleCtx,
577+
callback: RedisModuleInfoFunc,
578+
) -> Status {
579+
unsafe { RedisModule_RegisterInfoFunc.unwrap()(ctx, callback).into() }
580+
}
581+
582+
#[allow(clippy::not_unsafe_ptr_arg_deref)]
583+
pub fn add_info_section(
584+
ctx: *mut RedisModuleInfoCtx,
585+
name: Option<&str>, // assume NULL terminated
586+
) -> Status {
587+
let name = name.map(|n| {
588+
CString::new(n).unwrap()
589+
});
590+
if let Some(n) = name {
591+
unsafe { RedisModule_InfoAddSection.unwrap()(ctx, n.as_ptr() as *mut c_char).into() }
592+
} else {
593+
unsafe { RedisModule_InfoAddSection.unwrap()(ctx, ptr::null_mut()).into() }
594+
}
595+
}
596+
597+
#[allow(clippy::not_unsafe_ptr_arg_deref)]
598+
pub fn add_info_field_str(
599+
ctx: *mut RedisModuleInfoCtx,
600+
name: &str, // assume NULL terminated
601+
content: &str,
602+
) -> Status {
603+
let name = CString::new(name).unwrap();
604+
let content = RedisString::create(ptr::null_mut(), content);
605+
unsafe { RedisModule_InfoAddFieldString.unwrap()(ctx, name.as_ptr() as *mut c_char, content.inner).into() }
606+
}
607+
574608
#[cfg(feature = "experimental-api")]
575609
pub fn export_shared_api(
576610
ctx: *mut RedisModuleCtx,

0 commit comments

Comments
 (0)