-
-
Notifications
You must be signed in to change notification settings - Fork 158
feat(kprobe): Add basic kprobe support for x86_64 #852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit extends the TrapFrme method to facilitate use by callback functions in kprobes. In order to find the function address based on the symbol, we added the`addr_from_symbol` function. In the x86 and riscv64 architecture related codes, we have added the handling of breakpoint exceptions and single-step exceptions.
kernel/Cargo.toml
Outdated
@@ -54,7 +55,7 @@ uefi-raw = "=0.5.0" | |||
paste = "=1.0.14" | |||
slabmalloc = { path = "crates/rust-slabmalloc" } | |||
log = "0.4.21" | |||
|
|||
kprobe = { git = "https://github.com/os-module/eebpf" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不应该出现没有指定rev的外部依赖
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
从相关依赖库的代码量,以及内核可维护性的角度,没必要把kprobe的代码写到另一个仓库。这个是主线不能接受的~
我认为kprobe底层的实现是一个较为独立的模块,它不应该只局限于一个特定的内核当中。当然,我也可以把代码copy到主线当中。 |
我的建议是copy到内核里面,因为这样对于DragonOS而言更容易维护,也更好的跟其他内核机制做结合(依赖库的话版本管理很麻烦,当要同时改内核和库的时候,开发效率较低) |
好的 |
这里为rv编译失败了,可以参考 |
1 similar comment
这里为rv编译失败了,可以参考 |
kernel/crates/kprobe/src/arch/mod.rs
Outdated
impl From<KprobeBuilder> for KprobeBasic { | ||
fn from(value: KprobeBuilder) -> Self { | ||
let fault_handler = value | ||
.fault_handler | ||
.unwrap_or_else(|| ProbeHandler::new(|_| {})); | ||
KprobeBasic { | ||
symbol: value.symbol.unwrap(), | ||
symbol_addr: value.symbol_addr.unwrap(), | ||
offset: value.offset.unwrap(), | ||
pre_handler: value.pre_handler.unwrap(), | ||
post_handler: value.post_handler.unwrap(), | ||
fault_handler, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这一块感觉改为实现TryFrom,或者Builder的new就要接受这几个变量并初始化,而不是在From的时候unwrap,因为这是pub可见的,可能有外部使用者并不知道这几个字段是要初始化才能Into KprobeBasic,就会导致panic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好的
pub static DEBUG_KPROBE_LIST: SpinLock<BTreeMap<usize, Arc<Kprobe>>> = | ||
SpinLock::new(BTreeMap::new()); | ||
|
||
pub fn kprobe_init() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个空函数的作用是?是还没写完还是什么
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为现在的实现中暂时不需要初始化其它内容,也许在未来需要,所以留着这个接口
kernel/src/debug/kprobe/mod.rs
Outdated
} | ||
|
||
#[cfg(feature = "kprobe_test")] | ||
pub fn kprobe_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个测试会在哪里被运行吗,我好像没找到
kernel/src/debug/kprobe/test.rs
Outdated
|
||
#[inline(never)] | ||
#[no_mangle] | ||
pub fn detect_func(x: usize, y: usize) -> usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个应该不用pub可见吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
应该是的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个为啥要no_mangle呀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为当前的函数地址查找实现是直接判断函数名称是否相等。如果不用no_mangle,rust的名称会被混淆。后面这里需要被重新实现。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为当前的函数地址查找实现是直接判断函数名称是否相等。如果不用no_mangle,rust的名称会被混淆。后面这里需要被重新实现。
确实这个函数名的问题,可以单独拎出来讨论一下。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
个人理解还有几个TODO,可以补充一下:
- 直接计算指令长度,移除yaxpeax-x86/riscv64依赖项
- 改进
kernel/src/debug/kprobe/test.rs:7
中查找函数地址的方式,去除no_mangle
Support multiple kprobes registered in the same location
@chiichen 这个计算指令长度的依赖依然是必要的。因为我们需要在注册kprobe的时候建立好映射关系,这也就需要提前知道这个指令长度的信息。在Linux源代码中,也有相关的解析指令长度的实现。我这里把riscv的依赖去掉了,因为其指令长度可以通过一些标志位就知道。 |
LGTM |
@fslongjin 请问这个pr还有什么需要解决的吗? |
This commit extends the TrapFrme method to facilitate use by callback functions in kprobes. In order to find the function address based on the symbol, we added the
addr_from_symbol
function.In the x86 and riscv64 architecture related codes, we have added the handling of breakpoint exceptions and single-step exceptions.