Skip to content

Commit dd7c3c4

Browse files
committed
Introduce shm limiter
Signed-off-by: Bob Weinand <[email protected]>
1 parent 0ed274c commit dd7c3c4

File tree

18 files changed

+670
-216
lines changed

18 files changed

+670
-216
lines changed

ipc/src/platform/mem_handle.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ mod tests {
214214
let shm = ShmHandle::new(5).unwrap();
215215
let mut mapped = shm.map().unwrap();
216216
_ = mapped.as_slice_mut().write(&[1, 2, 3, 4, 5]).unwrap();
217-
let mapped = mapped.ensure_space(100000);
217+
mapped.ensure_space(100000);
218218
assert!(mapped.as_slice().len() >= 100000);
219219
let mut exp = vec![0u8; mapped.as_slice().len()];
220220
_ = (&mut exp[..5]).write(&[1, 2, 3, 4, 5]).unwrap();
@@ -228,7 +228,7 @@ mod tests {
228228
let shm = NamedShmHandle::create(path.clone(), 5).unwrap();
229229
let mut mapped = shm.map().unwrap();
230230
_ = mapped.as_slice_mut().write(&[1, 2, 3, 4, 5]).unwrap();
231-
let mapped = mapped.ensure_space(100000);
231+
mapped.ensure_space(100000);
232232
assert!(mapped.as_slice().len() >= 100000);
233233

234234
let other = NamedShmHandle::open(&path).unwrap().map().unwrap();

ipc/src/platform/unix/mem_handle.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,15 @@ impl NamedShmHandle {
107107
}
108108

109109
impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
110-
pub fn ensure_space(self, expected_size: usize) -> MappedMem<T> {
110+
pub fn ensure_space(&mut self, expected_size: usize) {
111111
if expected_size <= self.mem.get_shm().size {
112-
return self;
112+
return;
113113
}
114114

115-
let mut handle: T = self.into();
115+
// SAFETY: we'll overwrite the original memory later
116+
let mut handle: T = unsafe { std::ptr::read(self) }.into();
116117
_ = handle.resize(expected_size);
117-
handle.map().unwrap()
118+
unsafe { std::ptr::write(self, handle.map().unwrap()) };
118119
}
119120
}
120121

ipc/src/platform/unix/mem_handle_macos.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ impl NamedShmHandle {
126126
}
127127

128128
impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
129-
pub fn ensure_space(self, expected_size: usize) -> MappedMem<T> {
129+
pub fn ensure_space(&mut self, expected_size: usize) {
130130
if expected_size <= self.mem.get_shm().size {
131-
return self;
131+
return;
132132
}
133133
if expected_size > MAPPING_MAX_SIZE - page_size::get() {
134134
panic!(
@@ -138,7 +138,9 @@ impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
138138
);
139139
}
140140

141-
let mut handle: T = self.into();
141+
// SAFETY: we'll overwrite the original memory later
142+
let mut handle: T = unsafe { std::ptr::read(self) }.into();
143+
142144
let page_size = NonZeroUsize::try_from(page_size::get()).unwrap();
143145
unsafe {
144146
_ = handle.set_mapping_size(expected_size);
@@ -156,7 +158,8 @@ impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
156158
size.fetch_max(handle.get_size(), Ordering::SeqCst);
157159
_ = munmap(ptr, usize::from(page_size));
158160
}
159-
handle.map().unwrap()
161+
162+
unsafe { std::ptr::write(self, handle.map().unwrap()) };
160163
}
161164
}
162165

ipc/src/platform/windows/mem_handle.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ impl NamedShmHandle {
151151
}
152152

153153
impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
154-
pub fn ensure_space(mut self, expected_size: usize) -> MappedMem<T> {
154+
pub fn ensure_space(&mut self, expected_size: usize) {
155155
let current_size = self.mem.get_shm().size;
156156
if expected_size <= current_size {
157-
return self;
157+
return;
158158
}
159159
if expected_size > MAPPING_MAX_SIZE {
160160
panic!(
@@ -175,6 +175,5 @@ impl<T: FileBackedHandle + From<MappedMem<T>>> MappedMem<T> {
175175
PAGE_READWRITE,
176176
)
177177
};
178-
self
179178
}
180179
}

live-debugger-ffi/src/data.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
use datadog_live_debugger::debugger_defs::{ProbeMetadata, ProbeMetadataLocation};
55
use datadog_live_debugger::{
6-
Capture, DslString, EvaluateAt, InBodyLocation, MetricKind, ProbeCondition, ProbeValue,
7-
SpanProbeTarget,
6+
CaptureConfiguration, DslString, EvaluateAt, InBodyLocation, MetricKind, ProbeCondition,
7+
ProbeValue, SpanProbeTarget,
88
};
99
use ddcommon_ffi::slice::AsBytes;
1010
use ddcommon_ffi::{CharSlice, Option};
@@ -60,7 +60,7 @@ impl<'a> From<&'a datadog_live_debugger::MetricProbe> for MetricProbe<'a> {
6060
pub struct LogProbe<'a> {
6161
pub segments: &'a DslString,
6262
pub when: &'a ProbeCondition,
63-
pub capture: &'a Capture,
63+
pub capture: &'a CaptureConfiguration,
6464
pub capture_snapshot: bool,
6565
pub sampling_snapshots_per_second: u32,
6666
}
@@ -291,6 +291,7 @@ impl<'a> From<&'a datadog_live_debugger::LiveDebuggingData> for LiveDebuggingDat
291291
}
292292
}
293293

294-
pub extern "C" fn ddog_capture_defaults() -> Capture {
295-
Capture::default()
294+
#[no_mangle]
295+
pub extern "C" fn ddog_capture_defaults() -> CaptureConfiguration {
296+
CaptureConfiguration::default()
296297
}

live-debugger-ffi/src/evaluator.rs

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// License Version 2.0. This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021-Present Datadog, Inc.
33

44
use datadog_live_debugger::debugger_defs::SnapshotEvaluationError;
5-
use datadog_live_debugger::{DslString, ProbeCondition};
5+
use datadog_live_debugger::{DslString, ProbeCondition, ProbeValue};
66
use ddcommon_ffi::slice::AsBytes;
77
use ddcommon_ffi::CharSlice;
88
use std::borrow::Cow;
@@ -226,13 +226,8 @@ extern "C" fn ddog_drop_void_collection_string(void: VoidCollection) {
226226
}
227227
}
228228

229-
#[no_mangle]
230-
pub extern "C" fn ddog_evaluate_unmanaged_string(
231-
segments: &DslString,
232-
context: &mut c_void,
233-
errors: &mut Option<Box<Vec<SnapshotEvaluationError>>>,
234-
) -> VoidCollection {
235-
let string = ddog_evaluate_string(segments, context, errors).to_string();
229+
fn into_void_collection_string(s: &dyn ToString) -> VoidCollection {
230+
let string = s.to_string();
236231
let new = VoidCollection {
237232
count: string.len() as isize,
238233
elements: string.as_ptr() as *const c_void,
@@ -241,3 +236,58 @@ pub extern "C" fn ddog_evaluate_unmanaged_string(
241236
std::mem::forget(string);
242237
new
243238
}
239+
240+
#[no_mangle]
241+
pub extern "C" fn ddog_evaluate_unmanaged_string(
242+
segments: &DslString,
243+
context: &mut c_void,
244+
errors: &mut Option<Box<Vec<SnapshotEvaluationError>>>,
245+
) -> VoidCollection {
246+
into_void_collection_string(&ddog_evaluate_string(segments, context, errors))
247+
}
248+
249+
pub struct InternalIntermediateValue<'a>(datadog_live_debugger::IntermediateValue<'a, c_void>);
250+
251+
#[repr(C)]
252+
pub enum ValueEvaluationResult<'a> {
253+
Success(Box<InternalIntermediateValue<'a>>),
254+
Error(Box<Vec<SnapshotEvaluationError>>),
255+
}
256+
257+
#[no_mangle]
258+
pub extern "C" fn ddog_evaluate_value<'a>(
259+
value: &'a ProbeValue,
260+
context: &'a mut c_void,
261+
) -> ValueEvaluationResult<'a> {
262+
let mut ctx = EvalCtx::new(context);
263+
match datadog_live_debugger::eval_value(&mut ctx, value) {
264+
Ok(value) => ValueEvaluationResult::Success(Box::new(InternalIntermediateValue(value))),
265+
Err(error) => ValueEvaluationResult::Error(Box::new(vec![error])),
266+
}
267+
}
268+
269+
#[no_mangle]
270+
pub extern "C" fn ddog_evaluated_value_get<'a>(
271+
value: &'a InternalIntermediateValue<'a>,
272+
) -> IntermediateValue<'a> {
273+
(&value.0).into()
274+
}
275+
276+
#[no_mangle]
277+
pub extern "C" fn ddog_evaluated_value_drop(_: Box<InternalIntermediateValue>) {}
278+
279+
pub fn ddog_evaluated_value_into_string<'a>(
280+
value: Box<InternalIntermediateValue<'a>>,
281+
context: &'a mut c_void,
282+
) -> Cow<'a, str> {
283+
let mut ctx = EvalCtx::new(context);
284+
datadog_live_debugger::eval_intermediate_to_string(&mut ctx, value.0)
285+
}
286+
287+
#[no_mangle]
288+
pub extern "C" fn ddog_evaluated_value_into_unmanaged_string<'a>(
289+
value: Box<InternalIntermediateValue<'a>>,
290+
context: &'a mut c_void,
291+
) -> VoidCollection {
292+
into_void_collection_string(&ddog_evaluated_value_into_string(value, context))
293+
}

live-debugger-ffi/src/sender.rs

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
use ddcommon_ffi::CharSlice;
55
use std::borrow::Cow;
6+
use std::collections::hash_map;
7+
use std::mem::transmute;
68
// Alias to prevent cbindgen panic
79
use crate::data::Probe;
810
use datadog_live_debugger::debugger_defs::{
9-
Capture as DebuggerCaptureAlias, Captures, DebuggerData, DebuggerPayload, Entry, Fields,
10-
Snapshot, SnapshotEvaluationError, Value as DebuggerValueAlias,
11+
Capture as DebuggerCaptureAlias, Capture, Captures, DebuggerData, DebuggerPayload, Entry,
12+
Fields, Snapshot, SnapshotEvaluationError, Value as DebuggerValueAlias,
1113
};
1214
use datadog_live_debugger::sender::generate_new_id;
1315
use ddcommon_ffi::slice::AsBytes;
@@ -94,7 +96,7 @@ pub extern "C" fn ddog_create_exception_snapshot<'a>(
9496
debugger: DebuggerData {
9597
snapshot: Snapshot {
9698
captures: Some(Captures {
97-
r#return: Some(DebuggerCaptureAlias::default()),
99+
r#return: Some(Capture::default()),
98100
..Default::default()
99101
}),
100102
language: language.to_utf8_lossy(),
@@ -107,38 +109,33 @@ pub extern "C" fn ddog_create_exception_snapshot<'a>(
107109
};
108110
buffer.push(snapshot);
109111
unsafe {
110-
std::mem::transmute(
111-
buffer
112-
.last_mut()
113-
.unwrap()
114-
.debugger
115-
.snapshot
116-
.captures
117-
.as_mut()
118-
.unwrap()
119-
.r#return
120-
.as_mut()
121-
.unwrap(),
122-
)
112+
let captures = buffer
113+
.last_mut()
114+
.unwrap()
115+
.debugger
116+
.snapshot
117+
.captures
118+
.as_mut();
119+
transmute(captures.unwrap().r#return.as_mut().unwrap())
123120
}
124121
}
125122

123+
#[no_mangle]
126124
pub extern "C" fn ddog_create_log_probe_snapshot<'a>(
127-
buffer: &mut Box<DebuggerPayload<'a>>,
128125
probe: &'a Probe,
126+
message: Option<&CharSlice<'a>>,
129127
service: CharSlice<'a>,
130128
language: CharSlice<'a>,
131129
timestamp: u64,
132-
) -> *mut DebuggerCapture<'a> {
133-
*buffer = Box::new(DebuggerPayload {
130+
) -> Box<DebuggerPayload<'a>> {
131+
Box::new(DebuggerPayload {
134132
service: service.to_utf8_lossy(),
135133
source: "dd_debugger",
136134
timestamp,
137-
message: None,
135+
message: message.map(|m| m.to_utf8_lossy()),
138136
debugger: DebuggerData {
139137
snapshot: Snapshot {
140138
captures: Some(Captures {
141-
r#return: Some(DebuggerCaptureAlias::default()),
142139
..Default::default()
143140
}),
144141
language: language.to_utf8_lossy(),
@@ -148,20 +145,69 @@ pub extern "C" fn ddog_create_log_probe_snapshot<'a>(
148145
..Default::default()
149146
},
150147
},
151-
});
152-
unsafe {
153-
std::mem::transmute(
154-
buffer
155-
.debugger
156-
.snapshot
157-
.captures
158-
.as_mut()
159-
.unwrap()
160-
.r#return
161-
.as_mut()
162-
.unwrap(),
163-
)
164-
}
148+
})
149+
}
150+
151+
#[no_mangle]
152+
pub extern "C" fn ddog_update_payload_message<'a>(
153+
payload: &mut DebuggerPayload<'a>,
154+
message: CharSlice<'a>,
155+
) {
156+
payload.message = Some(message.to_utf8_lossy());
157+
}
158+
159+
#[no_mangle]
160+
pub unsafe extern "C" fn ddog_snapshot_entry<'a>(
161+
payload: &mut DebuggerPayload<'a>,
162+
) -> *mut DebuggerCapture<'a> {
163+
transmute(
164+
payload
165+
.debugger
166+
.snapshot
167+
.captures
168+
.as_mut()
169+
.unwrap()
170+
.entry
171+
.insert(Capture::default()),
172+
)
173+
}
174+
175+
#[no_mangle]
176+
pub unsafe extern "C" fn ddog_snapshot_lines<'a>(
177+
payload: &mut DebuggerPayload<'a>,
178+
line: u32,
179+
) -> *mut DebuggerCapture<'a> {
180+
transmute(
181+
match payload
182+
.debugger
183+
.snapshot
184+
.captures
185+
.as_mut()
186+
.unwrap()
187+
.lines
188+
.entry(line)
189+
{
190+
hash_map::Entry::Occupied(e) => e.into_mut(),
191+
hash_map::Entry::Vacant(e) => e.insert(Capture::default()),
192+
},
193+
)
194+
}
195+
196+
#[no_mangle]
197+
pub unsafe extern "C" fn ddog_snapshot_exit<'a>(
198+
payload: &mut DebuggerPayload<'a>,
199+
) -> *mut DebuggerCapture<'a> {
200+
transmute(
201+
payload
202+
.debugger
203+
.snapshot
204+
.captures
205+
.as_mut()
206+
.unwrap()
207+
.r#return
208+
.as_mut()
209+
.unwrap(),
210+
)
165211
}
166212

167213
#[no_mangle]
@@ -241,7 +287,10 @@ pub extern "C" fn ddog_evaluation_error_snapshot<'a>(
241287
service: service.to_utf8_lossy(),
242288
source: "dd_debugger",
243289
timestamp,
244-
message: Some(format!("Evaluation errors for probe id {}", probe.id)),
290+
message: Some(Cow::Owned(format!(
291+
"Evaluation errors for probe id {}",
292+
probe.id
293+
))),
245294
debugger: DebuggerData {
246295
snapshot: Snapshot {
247296
language: language.to_utf8_lossy(),

live-debugger/src/debugger_defs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub struct DebuggerPayload<'a> {
1111
pub source: &'static str,
1212
pub timestamp: u64,
1313
pub debugger: DebuggerData<'a>,
14-
pub message: Option<String>,
14+
pub message: Option<Cow<'a, str>>,
1515
}
1616

1717
#[derive(Serialize, Deserialize)]

0 commit comments

Comments
 (0)