mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
bpf: Add dump_stack() analogue to print to BPF stderr
Introduce a kernel function which is the analogue of dump_stack() printing some useful information and the stack trace. This is not exposed to BPF programs yet, but can be made available in the future. When we have a program counter for a BPF program in the stack trace, also additionally output the filename and line number to make the trace helpful. The rest of the trace can be passed into ./decode_stacktrace.sh to obtain the line numbers for kernel symbols. Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20250703204818.925464-7-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
f0c53fd4a7
commit
d7c431cafc
2 changed files with 50 additions and 0 deletions
|
@ -3616,8 +3616,10 @@ __printf(2, 3)
|
|||
int bpf_stream_stage_printk(struct bpf_stream_stage *ss, const char *fmt, ...);
|
||||
int bpf_stream_stage_commit(struct bpf_stream_stage *ss, struct bpf_prog *prog,
|
||||
enum bpf_stream_id stream_id);
|
||||
int bpf_stream_stage_dump_stack(struct bpf_stream_stage *ss);
|
||||
|
||||
#define bpf_stream_printk(ss, ...) bpf_stream_stage_printk(&ss, __VA_ARGS__)
|
||||
#define bpf_stream_dump_stack(ss) bpf_stream_stage_dump_stack(&ss)
|
||||
|
||||
#define bpf_stream_stage(ss, prog, stream_id, expr) \
|
||||
({ \
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/bpf_mem_alloc.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/refcount.h>
|
||||
|
@ -476,3 +477,50 @@ int bpf_stream_stage_commit(struct bpf_stream_stage *ss, struct bpf_prog *prog,
|
|||
llist_add_batch(head, tail, &stream->log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dump_stack_ctx {
|
||||
struct bpf_stream_stage *ss;
|
||||
int err;
|
||||
};
|
||||
|
||||
static bool dump_stack_cb(void *cookie, u64 ip, u64 sp, u64 bp)
|
||||
{
|
||||
struct dump_stack_ctx *ctxp = cookie;
|
||||
const char *file = "", *line = "";
|
||||
struct bpf_prog *prog;
|
||||
int num, ret;
|
||||
|
||||
rcu_read_lock();
|
||||
prog = bpf_prog_ksym_find(ip);
|
||||
rcu_read_unlock();
|
||||
if (prog) {
|
||||
ret = bpf_prog_get_file_line(prog, ip, &file, &line, &num);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
ctxp->err = bpf_stream_stage_printk(ctxp->ss, "%pS\n %s @ %s:%d\n",
|
||||
(void *)ip, line, file, num);
|
||||
return !ctxp->err;
|
||||
}
|
||||
end:
|
||||
ctxp->err = bpf_stream_stage_printk(ctxp->ss, "%pS\n", (void *)ip);
|
||||
return !ctxp->err;
|
||||
}
|
||||
|
||||
int bpf_stream_stage_dump_stack(struct bpf_stream_stage *ss)
|
||||
{
|
||||
struct dump_stack_ctx ctx = { .ss = ss };
|
||||
int ret;
|
||||
|
||||
ret = bpf_stream_stage_printk(ss, "CPU: %d UID: %d PID: %d Comm: %s\n",
|
||||
raw_smp_processor_id(), __kuid_val(current_real_cred()->euid),
|
||||
current->pid, current->comm);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = bpf_stream_stage_printk(ss, "Call trace:\n");
|
||||
if (ret)
|
||||
return ret;
|
||||
arch_bpf_stack_walk(dump_stack_cb, &ctx);
|
||||
if (ctx.err)
|
||||
return ctx.err;
|
||||
return bpf_stream_stage_printk(ss, "\n");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue