mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-09 21:25:24 +08:00
Deploying to gh-pages from @ eunomia-bpf/bpf-developer-tutorial@c120bb4912 🚀
This commit is contained in:
@@ -217,21 +217,21 @@ Userspace:
|
||||
<p>内核态 eBPF 程序的实现逻辑主要是借助 perf event,对程序的堆栈进行定时采样,从而捕获程序的执行流程。</p>
|
||||
<pre><code class="language-c">// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright (c) 2022 Meta Platforms, Inc. */
|
||||
#include "vmlinux.h"
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
|
||||
#include "profile.h"
|
||||
#include "profile.h"
|
||||
|
||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||
__uint(max_entries, 256 * 1024);
|
||||
} events SEC(".maps");
|
||||
} events SEC(".maps");
|
||||
|
||||
SEC("perf_event")
|
||||
SEC("perf_event")
|
||||
int profile(void *ctx)
|
||||
{
|
||||
int pid = bpf_get_current_pid_tgid() >> 32;
|
||||
@@ -266,13 +266,13 @@ int profile(void *ctx)
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||
__uint(max_entries, 256 * 1024);
|
||||
} events SEC(".maps");
|
||||
} events SEC(".maps");
|
||||
</code></pre>
|
||||
<p>这里定义了一个类型为 <code>BPF_MAP_TYPE_RINGBUF</code> 的 eBPF maps 。Ring Buffer 是一种高性能的循环缓冲区,用于在内核和用户空间之间传输数据。<code>max_entries</code> 设置了 Ring Buffer 的最大大小。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>定义 <code>perf_event</code> eBPF 程序:</p>
|
||||
<pre><code class="language-c">SEC("perf_event")
|
||||
<pre><code class="language-c">SEC("perf_event")
|
||||
int profile(void *ctx)
|
||||
</code></pre>
|
||||
<p>这里定义了一个名为 <code>profile</code> 的 eBPF 程序,它将在 perf 事件触发时执行。</p>
|
||||
@@ -342,7 +342,7 @@ int main(){
|
||||
/* Set up performance monitoring on a CPU/Core */
|
||||
pefd = perf_event_open(&attr, pid, cpu, -1, PERF_FLAG_FD_CLOEXEC);
|
||||
if (pefd < 0) {
|
||||
fprintf(stderr, "Fail to set up performance monitor on a CPU/Core\n");
|
||||
fprintf(stderr, "Fail to set up performance monitor on a CPU/Core\n");
|
||||
err = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -387,34 +387,34 @@ int main(){
|
||||
|
||||
for (i = 0; i < stack_sz; i++) {
|
||||
if (!result || result->size <= i || !result->entries[i].size) {
|
||||
printf(" %d [<%016llx>]\n", i, stack[i]);
|
||||
printf(" %d [<%016llx>]\n", i, stack[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result->entries[i].size == 1) {
|
||||
sym = &result->entries[i].syms[0];
|
||||
if (sym->path && sym->path[0]) {
|
||||
printf(" %d [<%016llx>] %s+0x%llx %s:%ld\n",
|
||||
printf(" %d [<%016llx>] %s+0x%llx %s:%ld\n",
|
||||
i, stack[i], sym->symbol,
|
||||
stack[i] - sym->start_address,
|
||||
sym->path, sym->line_no);
|
||||
} else {
|
||||
printf(" %d [<%016llx>] %s+0x%llx\n",
|
||||
printf(" %d [<%016llx>] %s+0x%llx\n",
|
||||
i, stack[i], sym->symbol,
|
||||
stack[i] - sym->start_address);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
printf(" %d [<%016llx>]\n", i, stack[i]);
|
||||
printf(" %d [<%016llx>]\n", i, stack[i]);
|
||||
for (j = 0; j < result->entries[i].size; j++) {
|
||||
sym = &result->entries[i].syms[j];
|
||||
if (sym->path && sym->path[0]) {
|
||||
printf(" %s+0x%llx %s:%ld\n",
|
||||
printf(" %s+0x%llx %s:%ld\n",
|
||||
sym->symbol, stack[i] - sym->start_address,
|
||||
sym->path, sym->line_no);
|
||||
} else {
|
||||
printf(" %s+0x%llx\n", sym->symbol,
|
||||
printf(" %s+0x%llx\n", sym->symbol,
|
||||
stack[i] - sym->start_address);
|
||||
}
|
||||
}
|
||||
@@ -431,23 +431,23 @@ static int event_handler(void *_ctx, void *data, size_t size)
|
||||
if (event->kstack_sz <= 0 && event->ustack_sz <= 0)
|
||||
return 1;
|
||||
|
||||
printf("COMM: %s (pid=%d) @ CPU %d\n", event->comm, event->pid, event->cpu_id);
|
||||
printf("COMM: %s (pid=%d) @ CPU %d\n", event->comm, event->pid, event->cpu_id);
|
||||
|
||||
if (event->kstack_sz > 0) {
|
||||
printf("Kernel:\n");
|
||||
printf("Kernel:\n");
|
||||
show_stack_trace(event->kstack, event->kstack_sz / sizeof(__u64), 0);
|
||||
} else {
|
||||
printf("No Kernel Stack\n");
|
||||
printf("No Kernel Stack\n");
|
||||
}
|
||||
|
||||
if (event->ustack_sz > 0) {
|
||||
printf("Userspace:\n");
|
||||
printf("Userspace:\n");
|
||||
show_stack_trace(event->ustack, event->ustack_sz / sizeof(__u64), event->pid);
|
||||
} else {
|
||||
printf("No Userspace Stack\n");
|
||||
printf("No Userspace Stack\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
Reference in New Issue
Block a user