Replies: 16 comments 9 replies
|
我们之前做过把 DWARF 调试信息保存到内核自身的 如果类似地把符号表,或者甚至整个带有调试信息的 elf 文件(通过 |
|
9.15-9.21进度:
TODO:
|
|
9.21-10.8 进度:
|
|
Starry 分支: ebpf tracepoint的文件系统接口使用方法 使用方法:
已
基于kprobe的eBPF系统调用统计 syscall_ebpf:在系统调用分发的入口插入kprobe并附着ebpf程序,统计每个系统调用的次数
基于tracepoint的eBPF mytrace: 在
|
|
10.9-10.17进展:
|
|
您可以把其中使用 https://github.com/nbdd0121/unwinding 代替 axbacktrace 的部分单独整理一下吗? |
|
10.25-10.31进展:
|
如何使用kretprobe获取函数返回值kretprobe是一种内核探针,允许我们在内核函数返回时执行自定义代码。通过kretprobe,我们可以捕获函数的返回值,并进行相应的处理。但是由于Rust和C语言的常见使用方法不同,可能会导致无法直接得到正确的返回值。 以以下Rust代码示例: fn add(x: usize, y: usize) -> usize {
return x + y;
}这里首先说明一下调用约定:在 x86-64 System V(Linux / macOS 等)下,整数/指针类型的前六个参数分别通过寄存器传递:rdi, rsi, rdx, rcx, r8, r9;第一个函数返回值通过 rax 返回, 第二个返回值通过 rdx 返回。 这段代码产生的汇编代码是: 0000000000015280 <add>:
15280: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
15284: c3 ret 也就是说,函数返回值存储在 rax 寄存器中。因此,我们可以直接通过pt_regs结构体中的rax字段来获取返回值。这和C语言的处理是类似的。 但是在内核项目中,大多数的函数的返回值通常用 以以下Rust代码示例: pub fn detect_func(x: usize, y: usize, z: Option<usize>) -> Option<usize> {
if let Some(z) = z {
Some(x + y + z)
} else {
None
}
}这段代码产生的汇编代码是: 0000000000015270 <detect_func>:
15270: 48 89 d0 mov %rdx,%rax
15273: 48 8d 14 37 lea (%rdi,%rsi,1),%rdx
15277: 48 01 ca add %rcx,%rdx
1527a: c3 ret
这里可以看到,对于 对于 尽管这可以处理大多数情况,但Rust有时会做进一步的优化,比如niche-optimized。在上面的示例中, 特殊情况处理在内核的一些函数中,似乎仍然无法通过获取寄存器的值来正确获取返回值。这还等待进一步的分析。 |
|
11.1-11.7 进展:
|
|
11.8-11.14进展:
|
|
11.15-11.21 进展:
独立create: |
基于uprobe的eBPF工作原理uprobe(用户空间探针)是一种用于在用户空间应用程序中动态插入探针的机制。它允许开发者在不修改应用程序源代码的情况下,监控和分析用户空间程序的行为。eBPF(扩展的伯克利包过滤器)是一种强大的内核技术,允许在内核中运行用户定义的程序,以实现高效的数据包处理和系统监控。eBPF与uprobe结合使用,可以实现对用户空间应用程序的深入监控和分析。 uprobe的工作原理uprobe通过在用户空间应用程序的特定函数入口处插入探针来工作。当应用程序执行到该函数时,uprobe会触发一个事件,允许eBPF程序捕获该事件并执行预定义的操作。以下是uprobe的工作流程:
eBPF与uprobe的结合以Aya框架中的uprobe为例,其挂载ebpf的接口是 uprobe的运行过程主要分为几个步骤:
pub enum UProbeAttachLocation<'a> {
/// The location of the target function in the target object file.
Symbol(&'a str),
/// The location of the target function in the target object file, offset by
/// the given number of bytes.
SymbolOffset(&'a str, u64),
/// The offset in the target object file, in bytes.
AbsoluteOffset(u64),
}
对于插入探针的过程,内核的处理过程:
由于共享库正常情况下被多个进程共享使用,因此全局插入uprobe探针时,理论上只需要在共享的物理页上修改指令,而对于指定pid插入uprobe探针时,则需要为该进程单独创建一份私有的内存页,并在该页上修改指令。 |
|
11.22-11.28:进展
|
|
11.29-12.05:进展
|
|
12.06-12.12:进展
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
为了在宏内核中引入eBPF的支持,内核最少需要实现以下功能:
为了实现一些常用eBPF框架的支持,比如Rust社区的Aya框架,接下来将按照以下路线逐步实现内核功能:
独立组件:
All reactions