Skip to main content

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}