Replies: 16 comments 9 replies
-
|
我们之前做过把 DWARF 调试信息保存到内核自身的 如果类似地把符号表,或者甚至整个带有调试信息的 elf 文件(通过 |
Beta Was this translation helpful? Give feedback.
-
|
9.15-9.21进度:
TODO:
|
Beta Was this translation helpful? Give feedback.
-
|
9.21-10.8 进度:
|
Beta Was this translation helpful? Give feedback.
-
|
Starry 分支: ebpf tracepoint的文件系统接口使用方法 使用方法:
已
基于kprobe的eBPF系统调用统计 syscall_ebpf:在系统调用分发的入口插入kprobe并附着ebpf程序,统计每个系统调用的次数
基于tracepoint的eBPF mytrace: 在
|
Beta Was this translation helpful? Give feedback.
-
|
10.9-10.17进展:
|
Beta Was this translation helpful? Give feedback.
-
|
10.18-10.24进展: |
Beta Was this translation helpful? Give feedback.
-
|
您可以把其中使用 https://github.com/nbdd0121/unwinding 代替 axbacktrace 的部分单独整理一下吗? |
Beta Was this translation helpful? Give feedback.
-
|
10.25-10.31进展:
|
Beta Was this translation helpful? Give feedback.
-
如何使用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。在上面的示例中, 特殊情况处理在内核的一些函数中,似乎仍然无法通过获取寄存器的值来正确获取返回值。这还等待进一步的分析。 |
Beta Was this translation helpful? Give feedback.
-
|
11.1-11.7 进展:
|
Beta Was this translation helpful? Give feedback.
-
|
11.8-11.14进展:
|
Beta Was this translation helpful? Give feedback.
-
|
11.15-11.21 进展:
独立create: |
Beta Was this translation helpful? Give feedback.
-
基于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探针时,则需要为该进程单独创建一份私有的内存页,并在该页上修改指令。 |
Beta Was this translation helpful? Give feedback.
-
|
11.22-11.28:进展
|
Beta Was this translation helpful? Give feedback.
-
|
11.29-12.05:进展
|
Beta Was this translation helpful? Give feedback.
-
|
12.06-12.12:进展
|
Beta Was this translation helpful? Give feedback.
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框架,接下来将按照以下路线逐步实现内核功能:
独立组件:
Beta Was this translation helpful? Give feedback.
All reactions