vmi_core/trace/mod.rs
1//! Field-shaped accessors for `#[tracing::instrument(fields(...))]`.
2//!
3//! Each function wraps a single VMI accessor so it returns a primitive
4//! `Option<T>` instead of `Result<Newtype<T>, VmiError>`.
5//!
6//! - Errors collapse to `None`, which drops the field from the span
7//! instead of poisoning it with an error string.
8//! - Newtype wrappers like `ProcessId(u32)` and `View(u16)` unwrap to
9//! their inner primitive, so structured-output subscribers emit a
10//! number rather than a `Debug`-formatted struct.
11//!
12//! # Examples
13//!
14//! ```ignore
15//! #[tracing::instrument(
16//! skip_all,
17//! fields(
18//! view = vmi::trace::event_view(vmi.event()),
19//! pid = vmi::trace::current_process_id(vmi),
20//! tid = vmi::trace::current_thread_id(vmi),
21//! )
22//! )]
23//! fn dispatch(...) { ... }
24//! ```
25
26mod hex;
27
28pub use self::hex::Hex;
29use crate::{
30 Architecture, VmiEvent, VmiState,
31 driver::VmiDriver,
32 os::{VmiOs, VmiOsProcess, VmiOsThread, VmiOsUserModule},
33};
34
35/// Returns the view of the given event, if available.
36pub fn event_view<Arch>(event: &VmiEvent<Arch>) -> Option<u16>
37where
38 Arch: Architecture,
39{
40 event.view().map(|view| view.0)
41}
42
43/// Returns the thread ID of the given thread, if available.
44pub fn thread_id<'a, Driver>(thread: &impl VmiOsThread<'a, Driver>) -> Option<u32>
45where
46 Driver: VmiDriver,
47{
48 thread.id().ok().map(|tid| tid.0)
49}
50
51/// Returns the process ID of the given process, if available.
52pub fn process_id<'a, Driver>(process: &impl VmiOsProcess<'a, Driver>) -> Option<u32>
53where
54 Driver: VmiDriver,
55{
56 process.id().ok().map(|pid| pid.0)
57}
58
59/// Returns the name of the process, if available.
60pub fn process_name<'a, Driver>(process: &impl VmiOsProcess<'a, Driver>) -> Option<String>
61where
62 Driver: VmiDriver,
63{
64 process.name().ok()
65}
66
67/// Returns the name of the given user module, if available.
68pub fn user_module_name<'a, Driver>(module: &impl VmiOsUserModule<'a, Driver>) -> Option<String>
69where
70 Driver: VmiDriver,
71{
72 module.name().ok()
73}
74
75/// Returns the thread ID of the current thread, if available.
76pub fn current_thread_id<Os>(vmi: &VmiState<Os>) -> Option<u32>
77where
78 Os: VmiOs,
79{
80 thread_id(&vmi.os().current_thread().ok()?)
81}
82
83/// Returns the process ID of the current process, if available.
84pub fn current_process_id<Os>(vmi: &VmiState<Os>) -> Option<u32>
85where
86 Os: VmiOs,
87{
88 process_id(&vmi.os().current_process().ok()?)
89}
90
91/// Returns the name of the current process, if available.
92pub fn current_process_name<Os>(vmi: &VmiState<Os>) -> Option<String>
93where
94 Os: VmiOs,
95{
96 process_name(&vmi.os().current_process().ok()?)
97}