forked from open-telemetry/opentelemetry-ebpf-profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
integration_test.ebpf.c
96 lines (83 loc) · 2.61 KB
/
integration_test.ebpf.c
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
90
91
92
93
94
95
96
// This file contains the code and map definitions that are used in integration tests only.
#include "bpfdefs.h"
#include "frametypes.h"
#include "types.h"
#include "extmaps.h"
#include "tracemgmt.h"
extern bpf_map_def kernel_stackmap;
static inline __attribute__((__always_inline__))
void send_sample_traces(void *ctx, u64 pid, s32 kstack) {
// Use the per CPU record for trace storage: it's too big for stack.
PerCPURecord *record = get_pristine_per_cpu_record();
if (!record) {
return; // unreachable
}
// Single native frame, no kernel trace.
Trace *trace = &record->trace;
// Use COMM as a marker for our test traces. COMM[3] serves as test case ID.
trace->comm[0] = 0xAA;
trace->comm[1] = 0xBB;
trace->comm[2] = 0xCC;
trace->comm[3] = 1;
trace->pid = pid;
trace->tid = pid;
trace->kernel_stack_id = -1,
trace->stack_len = 1;
trace->frames[0] = (Frame) {
.kind = FRAME_MARKER_NATIVE,
.file_id = 1337,
.addr_or_line = 21,
};
send_trace(ctx, trace);
// Single native frame, with kernel trace.
trace->comm[3] = 2;
trace->kernel_stack_id = kstack;
send_trace(ctx, trace);
// Single Python frame.
trace->comm[3] = 3;
trace->kernel_stack_id = -1;
trace->stack_len = 3;
trace->frames[0] = (Frame) {
.kind = FRAME_MARKER_NATIVE,
.file_id = 1337,
.addr_or_line = 42,
};
trace->frames[1] = (Frame) {
.kind = FRAME_MARKER_NATIVE,
.file_id = 1338,
.addr_or_line = 21,
};
trace->frames[2] = (Frame) {
.kind = FRAME_MARKER_PYTHON,
.file_id = 1339,
.addr_or_line = 22,
};
send_trace(ctx, trace);
// Maximum length native trace.
trace->comm[3] = 4;
trace->stack_len = MAX_FRAME_UNWINDS;
trace->kernel_stack_id = kstack;
#pragma unroll
for (u64 i = 0; i < MAX_FRAME_UNWINDS; ++i) {
// NOTE: this init schema eats up a lot of instructions. If we need more
// space later, we can instead just init `.kind` and a few fields in the
// start, middle, and end of the trace.
trace->frames[i] = (Frame) {
.kind = FRAME_MARKER_NATIVE,
.file_id = ~i,
.addr_or_line = i,
};
}
send_trace(ctx, trace);
}
// tracepoint__sched_switch fetches the current kernel stack ID from kernel_stackmap and
// communicates it to userspace via kernel_stack_id map.
SEC("tracepoint/sched/sched_switch")
int tracepoint__sched_switch(void *ctx) {
u64 id = bpf_get_current_pid_tgid();
u64 pid = id >> 32;
s32 kernel_stack_id = bpf_get_stackid(ctx, &kernel_stackmap, BPF_F_REUSE_STACKID);
printt("pid %lld with kernel_stack_id %d", pid, kernel_stack_id);
send_sample_traces(ctx, pid, kernel_stack_id);
return 0;
}