Skip to content

Commit 35a60c0

Browse files
committed
Prevent the name_to_mib from panicking
1 parent be742bc commit 35a60c0

1 file changed

Lines changed: 69 additions & 36 deletions

File tree

microchassis/src/profiling/mallctl.rs

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -64,91 +64,121 @@ pub fn enabled() -> Result<bool, Error> {
6464
unsafe { raw::read_mib(&*MIB_OPT_PROF).map_err(Into::into) }
6565
}
6666

67+
// TODO: consider a guard pattern instead of checking for each command.
68+
fn if_enabled<F, T>(f: F) -> Result<T, Error>
69+
where
70+
F: FnOnce() -> Result<T, Error>,
71+
{
72+
if enabled()? {
73+
f()
74+
} else {
75+
Err(Error::ProfilingDisabled)
76+
}
77+
}
78+
6779
/// Writes `prof.active`.
6880
#[inline]
6981
pub fn set_active(value: bool) -> Result<(), Error> {
70-
// SAFETY: use correct type (bool) for this mallctl command.
71-
unsafe { raw::write_mib(&*MIB_PROF_ACTIVE, value).map_err(Into::into) }
82+
if_enabled(move || {
83+
// SAFETY: use correct type (bool) for this mallctl command.
84+
unsafe { raw::write_mib(&*MIB_PROF_ACTIVE, value).map_err(Into::into) }
85+
})
7286
}
7387

7488
/// Reads `prof.active`.
7589
#[inline]
7690
pub fn active() -> Result<bool, Error> {
77-
// SAFETY: use correct type (bool) for this mallctl command.
78-
unsafe { raw::read_mib(&*MIB_PROF_ACTIVE).map_err(Into::into) }
91+
if_enabled(move || {
92+
// SAFETY: use correct type (bool) for this mallctl command.
93+
unsafe { raw::read_mib(&*MIB_PROF_ACTIVE).map_err(Into::into) }
94+
})
7995
}
8096

8197
/// Writes `prof.thread_active_init`.
8298
#[inline]
8399
pub fn set_thread_active_init(value: bool) -> Result<(), Error> {
84-
// SAFETY: use correct param type (bool) for this mallctl command.
85-
unsafe { raw::write_mib(&*MIB_PROF_THREAD_ACTIVE_INIT, value).map_err(Into::into) }
100+
if_enabled(move || {
101+
// SAFETY: use correct param type (bool) for this mallctl command.
102+
unsafe { raw::write_mib(&*MIB_PROF_THREAD_ACTIVE_INIT, value).map_err(Into::into) }
103+
})
86104
}
87105

88106
/// Reads `prof.thread_active_init`.
89107
#[inline]
90108
pub fn thread_active_init() -> Result<bool, Error> {
91-
// SAFETY: use correct return type (bool) for this mallctl command.
92-
unsafe { raw::read_mib(&*MIB_PROF_THREAD_ACTIVE_INIT).map_err(Into::into) }
109+
if_enabled(move || {
110+
// SAFETY: use correct return type (bool) for this mallctl command.
111+
unsafe { raw::read_mib(&*MIB_PROF_THREAD_ACTIVE_INIT).map_err(Into::into) }
112+
})
93113
}
94114

95115
/// Writes `thread.prof.active`.
96116
#[inline]
97117
pub fn set_thread_active(value: bool) -> Result<(), Error> {
98-
// SAFETY: use correct param type (bool) for this mallctl command.
99-
unsafe { raw::write_mib(&*MIB_THREAD_PROF_ACTIVE, value).map_err(Into::into) }
118+
if_enabled(move || {
119+
// SAFETY: use correct param type (bool) for this mallctl command.
120+
unsafe { raw::write_mib(&*MIB_THREAD_PROF_ACTIVE, value).map_err(Into::into) }
121+
})
100122
}
101123

102124
/// Reads `thread.prof.active`.
103125
#[inline]
104126
pub fn thread_active() -> Result<bool, Error> {
105-
// SAFETY: use correct return type (bool) for this mallctl command.
106-
unsafe { raw::read_mib(&*MIB_THREAD_PROF_ACTIVE).map_err(Into::into) }
127+
if_enabled(move || {
128+
// SAFETY: use correct return type (bool) for this mallctl command.
129+
unsafe { raw::read_mib(&*MIB_THREAD_PROF_ACTIVE).map_err(Into::into) }
130+
})
107131
}
108132

109133
/// Writes `prof.reset`. Optionally settings a new sample interval.
110134
#[allow(clippy::option_if_let_else, clippy::borrow_as_ptr)]
111135
#[inline]
112136
pub fn reset(sample: Option<usize>) -> Result<(), Error> {
113-
let value = match sample {
114-
Some(mut sample) => &mut sample as *mut _,
115-
None => ptr::null_mut(),
116-
};
117-
// SAFETY: use correct param type (*size_t) for this mallctl command.
118-
unsafe { write_mib_ptr(&*MIB_PROF_RESET, value).map_err(Into::into) }
137+
if_enabled(move || {
138+
let value = match sample {
139+
Some(mut sample) => &mut sample as *mut _,
140+
None => ptr::null_mut(),
141+
};
142+
// SAFETY: use correct param type (*size_t) for this mallctl command.
143+
unsafe { write_mib_ptr(&*MIB_PROF_RESET, value).map_err(Into::into) }
144+
})
119145
}
120146

121147
/// Reads `prof.lg_sample`.
122148
#[inline]
123149
pub fn sample_interval() -> Result<usize, Error> {
124-
// SAFETY: use correct return type (size_t) for this mallctl command.
125-
unsafe { raw::read_mib(&*MIB_PROF_LG_SAMPLE).map_err(Into::into) }
150+
if_enabled(move || {
151+
// SAFETY: use correct return type (size_t) for this mallctl command.
152+
unsafe { raw::read_mib(&*MIB_PROF_LG_SAMPLE).map_err(Into::into) }
153+
})
126154
}
127155

128156
/// Writes `prof.dump` causing a profile dump into a file.
129157
/// If a path is given, use the file as dump target and return its content.
130158
/// If not, jemalloc dumps the profile to a file based on name pattern.
131159
#[inline]
132160
pub fn dump(path: Option<&str>) -> Result<Option<Vec<u8>>, Error> {
133-
let ptr = match path {
134-
Some(s) => ffi::CString::new(s)?.into_bytes_with_nul().as_ptr(),
135-
None => ptr::null(),
136-
};
161+
if_enabled(move || {
162+
let ptr = match path {
163+
Some(s) => ffi::CString::new(s)?.into_bytes_with_nul().as_ptr(),
164+
None => ptr::null(),
165+
};
137166

138-
// SAFETY: use correct param type (*char+\0) for this mallctl command.
139-
unsafe {
140-
raw::write_mib(&*MIB_PROF_DUMP, ptr)?;
141-
}
167+
// SAFETY: use correct param type (*char+\0) for this mallctl command.
168+
unsafe {
169+
raw::write_mib(&*MIB_PROF_DUMP, ptr)?;
170+
}
142171

143-
match path {
144-
Some(path) => {
145-
let mut f = fs::File::open(path)?;
146-
let mut buf = Vec::new();
147-
io::copy(&mut f, &mut buf)?;
148-
Ok(Some(buf))
172+
match path {
173+
Some(path) => {
174+
let mut f = fs::File::open(path)?;
175+
let mut buf = Vec::new();
176+
io::copy(&mut f, &mut buf)?;
177+
Ok(Some(buf))
178+
}
179+
None => Ok(None),
149180
}
150-
None => Ok(None),
151-
}
181+
})
152182
}
153183

154184
pub fn stats() -> Result<Vec<u8>, Error> {
@@ -176,6 +206,9 @@ unsafe fn write_mib_ptr<T>(mib: &[usize], value: *mut T) -> Result<(), Error> {
176206

177207
#[derive(thiserror::Error, fmt::Debug)]
178208
pub enum Error {
209+
#[error("mallctl: profiling disabled")]
210+
ProfilingDisabled,
211+
179212
#[error("mallctl error: {0}")]
180213
Mallctl(#[from] MallctlError),
181214

0 commit comments

Comments
 (0)