-
Notifications
You must be signed in to change notification settings - Fork 536
Expand file tree
/
Copy pathlib.rs
More file actions
89 lines (82 loc) · 3.54 KB
/
Copy pathlib.rs
File metadata and controls
89 lines (82 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0
//! Thin cdylib wrapping `libdd-profiling-heap-gotter` (crates.io) under stable
//! `extern "C"` symbols for the Python ctypes activator to dlopen.
/// Install GOT overrides for supported heap-allocation symbols and report
/// whether the install actually took effect.
///
/// Returns the result of `install_heap_overrides`, i.e. whether at least one
/// allocator symbol's GOT entry was resolved and patched (so hooks will run).
///
/// After a successful install, a `fork()` child inherits the mapping and the
/// patched GOT, so a second native install is usually unnecessary. Upstream has
/// no `pthread_atfork` child reset for the process-global registry mutex
/// (`GLOBAL_OVERRIDES`); forking during an in-flight `install()`/`update()` can
/// leave that mutex locked in the child — treat mid-install fork as unsafe.
/// Prefer installing on the main thread (or in the worker after fork). The
/// Python activator's `_armed` skip avoids re-entering this cdylib after a
/// successful install on the common post-fork path; that is not a claim that
/// all inherited native state is fork-safe.
///
/// # Safety
///
/// C ABI entry point with no arguments and no pointers; always safe to call.
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_install() -> bool {
libdd_profiling_heap_gotter::install_heap_overrides()
}
/// Return whether heap GOT overrides are currently installed in this process.
/// Always `false` on non-Linux targets.
///
/// # Safety
///
/// C ABI entry point with no arguments and no pointers; always safe to call.
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_is_installed() -> bool {
libdd_profiling_heap_gotter::heap_overrides_are_installed()
}
/// Set the mean sample distance (bytes between samples) for the heap sampler.
/// Must be called before `ddtrace_heap_gotter_install` to take effect.
///
/// # Safety
///
/// C ABI entry point; always safe to call.
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_set_sampling_distance(distance: u64) {
libdd_profiling_heap_gotter::set_default_sampling_distance(distance);
}
/// Re-scan loaded libraries and patch any newly-introduced GOT entries.
/// Normally called automatically from the internal `dlopen` hook; exposed here
/// for cases where the Python side loads a `.so` and wants immediate coverage.
///
/// # Safety
///
/// C ABI entry point with no arguments and no pointers; always safe to call.
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_update() {
libdd_profiling_heap_gotter::update_heap_overrides();
}
/// Compile-time live-heap capability: `true` when built with the `live-heap`
/// feature (`ddheap:free` + retain flagging). Not a runtime toggle; keep in
/// lockstep with Cargo.toml's forward to `libdd-profiling-heap-gotter/live-heap`.
///
/// # Safety
///
/// C ABI entry point with no arguments and no pointers; always safe to call.
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_live_heap_enabled() -> bool {
cfg!(feature = "live-heap")
}
/// Test-only: number of times a patched hook has run in this process. Lets
/// integration tests prove the patched GOT was actually exercised without a
/// live eBPF attach. Only present when built with the `test-support` feature;
/// never compiled into shipped wheels.
///
/// # Safety
///
/// C ABI entry point with no arguments and no pointers; always safe to call.
#[cfg(feature = "test-support")]
#[no_mangle]
pub extern "C" fn ddtrace_heap_gotter_test_hook_hits() -> u64 {
libdd_profiling_heap_gotter::test_hook_hits()
}