-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tracers for process exits and memory unmaps
This change is important for longer profiling sessions (such as continuous profiling) to be informed of processes that exit as well of memory mappings that get unmapped. The events are only sent for mappings and processes that are already stored in the BPF maps. Additional changes ================== - Move the try_recv for the events from a busy loop to a waiting time of 250ms, as this otherwise uses too much CPU for no good reason; - Change build.rs to rebuild if any header or source file under src/bpf is modified; - Fixes a bug where the unwind information was being updated even if it wasn't dirty; Future work =========== - Improve the way the BPF headers and code are split; - Actually mark the memory mappings that get unmapped as so in the userspace data structures; - Use the fact that a memory mapping has been unmapped or a process has exited to for example clean up some of the data we store; Test Plan ========= Ran lightswitch several times without issues.
- Loading branch information
1 parent
d92afad
commit e2328b4
Showing
12 changed files
with
422 additions
and
119 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
pub mod profiler_bindings; | ||
pub mod profiler_skel; | ||
pub mod tracers_bindings; | ||
pub mod tracers_skel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
static __always_inline mapping_t* find_mapping(int per_process_id, u64 pc) { | ||
struct exec_mappings_key key = {}; | ||
key.prefix_len = PREFIX_LEN; | ||
key.pid = __builtin_bswap32((u32) per_process_id); | ||
key.data = __builtin_bswap64(pc); | ||
|
||
mapping_t *mapping = bpf_map_lookup_elem(&exec_mappings, &key); | ||
|
||
if (mapping == NULL) { | ||
LOG("[error] no mapping found for pc %llx", pc); | ||
bump_unwind_error_mapping_not_found(); | ||
return NULL; | ||
} | ||
|
||
if (pc < mapping->begin || pc >= mapping->end) { | ||
LOG("[error] pc %llx not contained within begin: %llx end: %llx", pc, mapping->begin, mapping->end); | ||
bump_unwind_error_mapping_does_not_contain_pc(); | ||
return NULL; | ||
} | ||
|
||
return mapping; | ||
} | ||
|
||
static __always_inline bool process_is_known(int per_process_id) { | ||
struct exec_mappings_key key = {}; | ||
key.prefix_len = PREFIX_LEN; | ||
key.pid = __builtin_bswap32((u32) per_process_id); | ||
key.data = 0; | ||
|
||
return bpf_map_lookup_elem(&exec_mappings, &key) != NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#ifndef __LIGHTSWITCH_SHARED_BPF_MAPS__ | ||
#define __LIGHTSWITCH_SHARED_BPF_MAPS__ | ||
|
||
#include <bpf/bpf_tracing.h> | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_LPM_TRIE); | ||
__type(key, struct exec_mappings_key); | ||
__type(value, mapping_t); | ||
__uint(map_flags, BPF_F_NO_PREALLOC); | ||
__uint(max_entries, MAX_PROCESSES * 200); | ||
} exec_mappings SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, u32); | ||
__type(value, struct unwinder_stats_t); | ||
} percpu_stats SEC(".maps"); | ||
|
||
|
||
#define DEFINE_COUNTER(__func__name) \ | ||
static void bump_unwind_##__func__name() { \ | ||
u32 zero = 0; \ | ||
struct unwinder_stats_t *unwinder_stats = \ | ||
bpf_map_lookup_elem(&percpu_stats, &zero); \ | ||
if (unwinder_stats != NULL) { \ | ||
unwinder_stats->__func__name++; \ | ||
} \ | ||
} | ||
|
||
DEFINE_COUNTER(total); | ||
DEFINE_COUNTER(success_dwarf); | ||
DEFINE_COUNTER(error_truncated); | ||
DEFINE_COUNTER(error_unsupported_expression); | ||
DEFINE_COUNTER(error_unsupported_frame_pointer_action); | ||
DEFINE_COUNTER(error_unsupported_cfa_register); | ||
DEFINE_COUNTER(error_catchall); | ||
DEFINE_COUNTER(error_should_never_happen); | ||
DEFINE_COUNTER(error_pc_not_covered); | ||
DEFINE_COUNTER(error_mapping_not_found); | ||
DEFINE_COUNTER(error_mapping_does_not_contain_pc); | ||
DEFINE_COUNTER(error_chunk_not_found); | ||
DEFINE_COUNTER(error_binary_search_exausted_iterations); | ||
DEFINE_COUNTER(error_sending_new_process_event); | ||
DEFINE_COUNTER(error_cfa_offset_did_not_fit); | ||
|
||
#endif |
Oops, something went wrong.