【问题标题】:linux proc size limit problemslinux proc 大小限制问题
【发布时间】:2015-02-13 10:39:47
【问题描述】:

我正在尝试编写一个 linux 内核模块,该模块可以将其他模块的内容转储到 /proc 文件(用于分析)。原则上它可以工作,但似乎我遇到了一些缓冲区限制等。我对 Linux 内核开发还很陌生,所以我也很感激任何与特定问题无关的建议。

用于存储模块的内存在这个函数中分配:

char *get_module_dump(int module_num)
{
    struct module *mod = unhiddenModules[module_num];
    char *buffer;
    buffer = kmalloc(mod->core_size * sizeof(char), GFP_KERNEL);
    memcpy((void *)buffer, (void *)startOf(mod), mod->core_size);
    return buffer;
}

'unhiddenModules' 是一个模块结构数组

然后这里交给proc创建:

void create_module_dump_proc(int module_number)
{
    struct proc_dir_entry *dump_module_proc;
    dump_size = unhiddenModules[module_number]->core_size;
    module_buffer = get_module_dump(module_number);
    sprintf(current_dump_file_name, "%s_dump", unhiddenModules[module_number]->name);
    dump_module_proc = proc_create_data(current_dump_file_name, 0, dump_proc_folder, &dump_fops, module_buffer);
}

proc读取函数如下:

ssize_t dump_proc_read(struct file *filp, char *buf, size_t count, loff_t *offp)
{
    char *data;
    ssize_t ret;
    data = PDE_DATA(file_inode(filp));
    ret = copy_to_user(buf, data, dump_size);
    *offp += dump_size - ret;
    if (*offp > dump_size)
        return 0;
    else
        return dump_size;
}

正确转储较小的模块,但如果模块大于 126,796 字节,则仅写入前 126,796 字节,从 proc 文件读取时会显示此错误:

*** Error in `cat': free(): invalid next size (fast): 0x0000000001f4a040 ***

我似乎遇到了一些限制,但我找不到任何东西。该错误似乎与内存泄漏有关,但缓冲区应该足够大,所以我看不到实际发生的位置。

【问题讨论】:

  • 也许你可以使用一些静态代码分析来检查内存泄漏。为什么不释放内存?
  • 还有一件可疑的事情是传递给cat 的数据可能不会以空值终止。尝试 null 终止您的 module_buffer
  • kmalloc 分配连续的内存块。我建议切换到vmalloc。
  • 我实际上是在释放内存(在卸载模具时)。此外,模块缓冲区没有被空终止不应该是问题,因为较小的模块被正确转储并且错误发生在到达结束之前。而且我已经尝试了 kmalloc 和 vmalloc,但遗憾的是它没有任何区别:(

标签: c linux linux-kernel proc


【解决方案1】:

procfs 的读写操作限制为 PAGE_SIZE(一页)。通常 seq_file 用于迭代条目(在您的情况下为模块?)以读取和/或写入较小的块。由于您只遇到较大数据的问题,我怀疑这里就是这种情况。

如果您不熟悉 seq_files,请查看 herehere

【讨论】:

  • 我不知道这是否真的是这里的问题。根据getconf PAGE_SIZE,页面大小为4096(也比126796小得多)
【解决方案2】:

一个可疑的事情是在 dump_proc_read 你没有使用“count”参数。我本来希望 copy_to_user 将“count”作为第三个参数而不是“dump_size”(在随后的计算中也是如此)。你这样做的方式,总是将 dump_size 字节复制到用户空间,而不管应用程序期望的数据大小。 dump_size 越大,损坏的用户区域就越大。

【讨论】:

  • 我寻找了 proc 读取函数的其他实现,并在此处尝试了一个:@silentnights 中的 link 带有计数,实际上这适用于较大的文件。我最初的实现达到一定限制的原因对我来说可能仍然是个谜,但只要它现在正常工作就可以了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 2017-03-23
  • 2020-05-04
相关资源
最近更新 更多