我编写了一个内核模块(一个字符设备),每当我写到这个模块时,它就会注册新的KProbes。
我有一个包含struct kprobe的结构。当我调用register_kprobe()时,它返回-EINVAL。但是,当我将一个虚拟字符数组添加到(可能还有其他一些数据类型)时,KProbe注册就会成功。
探针注册
struct my_struct *container = kmalloc(sizeof(struct my_struct));
(container->probe).addr = (kprobe_opcode_t *) kallsyms_lookup_name("my_exported_fn"); /* my_exported_fn is in code section */
(container->probe).pre_handler = Pre_Handler;
(container->probe).post_handler = Post_Handler;
register_probe(&container->probe);
/* Returns -EINVAL if my_struct contains only `struct kprobe`. */不起作用:
struct my_struct {
struct kprobe probe;
}工作:
struct my_struct {
char dummy[512]; /* At 512, it gets consistently registered. At 256, sometimes (maybe one out of 5 - 10 times get registered) */
struct kprobe probe;
}为什么它需要额外的内存才能出现在结构中?
发布于 2017-09-30 06:45:54
这可能是非对齐内存访问,但在这种情况下(我指的是编辑之前的原始代码),我怀疑数据没有被正确初始化。即register_kprobe() 呼叫 kprobe_addr()函数,这反过来意味着下面的检查
if ((symbol_name && addr) || (!symbol_name && !addr))
goto invalid;
...
invalid:
return ERR_PTR(-EINVAL);因此,如果您确实初始化了addr而不初始化symbol_name,那么在某些情况下,后者可能是一个垃圾指针。也就是说,kmalloc()不对分配的内存进行零点化,而且,根据请求的大小,它可能从不同的池(有不同的池来提供不同大小的对象)获取适当大小的内存对象,并且当您人为地增加结构的大小时,kmalloc()必须从一个合适的池中分配一个更大的对象。从这个角度来看,这种对象不可能偶尔包含垃圾(因为更大的块被请求的频率较低)。
总之,我建议将内存块归零或使用kzalloc()。
https://stackoverflow.com/questions/46498699
复制相似问题