Skip to content

Commit 7313be9

Browse files
authored
bpf: explain register updation calculations for JIT stackwalking (#1863)
Fixes #1710 <!-- copilot:poem -->
2 parents d6e4401 + a0a3dcb commit 7313be9

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

bpf/cpu/cpu.bpf.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,9 +773,18 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
773773
return 1;
774774
}
775775

776-
// TODO(sylfrena): add comments to explain calculations
776+
// Stacktraces are essentially a list of saved return addresses from function calls pushed onto a stack
777+
// The base pointer (`rbp` in x86_64) is a register pushed onto the stack and points to/references the beginning of the stack
778+
// The stack pointer(`rsp`) points to the frame at the `rbp`, updating the top of the stack to 8 bytes ahead of the `rbp`
779+
// When the current instruction is pushed, top of the stack moves up by 1 frame, updating `rsp` by another 8 bytes
780+
// Hence, we update current stack pointer by 16 bytes ahead of `rbp`
777781
unwind_state->sp = unwind_state->bp + 16;
778782
unwind_state->bp = next_fp;
783+
// Rewinding the program counter to get the instruction pointer for the previous function
784+
// would be ideal but is unreliable in `x86` due to variable width encoding. We can ensure correctness only by disassembling the `.text` section which would be unfeasible.
785+
// Since return addresses always point to the next instruction to be executed after returning from the function
786+
// (and stack grows downwards), subtracting 1 from the current `ra` gives us the current instruction pointer location,
787+
// if not the exact instruction boundary
779788
unwind_state->ip = ra - 1;
780789
len = unwind_state->stack.len;
781790

0 commit comments

Comments
 (0)