【问题标题】:Saving a size_t in a raw mem block and getting it back将 size_t 保存在原始内存块中并取回
【发布时间】:2013-09-25 21:11:20
【问题描述】:

我将size_t 类型的数据保存在内核态的原始内存块中,然后我将整个内存块发送到用户态并尝试取回size_t 值。

不保证该类型在内核和用户空间上的大小相同,所以我想知道保存该值然后恢复它的最佳方法是什么。

编辑:

或者,也许只是保存另一种类型的数据,而不是两边大小相同,并且可以在size_t/从size_t进行转换(或转换而不会丢失数据)

编辑 2:

我正在以以下格式保存我的数据:

(size_of_data_chunk)(data_chunk)(size_of_data_chunk)(data_chunk)...

常用代码:

内核领域的代码:

void add_chunk(membuffer *buffer, void *chunk, size_t size){

    if(buffer->data != NULL){
        buffer->data = krealloc(buffer->data, buffer->len + sizeof(size_t) + size, GFP_KERNEL);
        buffer->len += sizeof(size_t) + size;

        memcpy(buffer->data + buffer->len, &size, sizeof(size_t));
        memcpy(buffer->data + buffer->len + sizeof(size_t), chunk, size);
    }else{

        buffer->data = kmalloc(sizeof(size_t) + size, GFP_KERNEL);
        buffer->len = sizeof(size_t) + size;

        memcpy(buffer->data, &size, sizeof(size_t));
        memcpy(buffer->data + sizeof(size_t), chunk, size);

    }

}

用户空间中的代码:

void *get_chunk(membuffer *buffer){

    size_t *size;
    void *new_buffer;
    void *chunk = NULL;

    size = malloc(sizeof(size_t));

    memcpy(size, buffer->data, sizeof(size_t));

    chunk = malloc(*size);
    memcpy(chunk, buffer->data + sizeof(size_t), *size);

    buffer->data = malloc(buffer->len - sizeof(size_t) - *size);

    memcpy(buffer->data, buffer->data + sizeof(size_t) + *size, buffer->len - sizeof(size_t) - *size);

    free(size);

    return chunk;
}

请注意,我知道每个块将包含什么类型的数据,因此我不需要保存类型或任何其他信息,只需保存块的大小和块本身。

另请注意,这是我尚未完成(又名测试)的代码。也许有些free 不见了。

【问题讨论】:

  • 当你说“原始内存块”时,你到底在使用什么机制(双方)?
  • @BenjaminLeinweber 请看我的编辑
  • 我不是这个意思。您如何在用户空间中分配内存,然后如何尝试在内核空间中访问它?您使用的具体系统调用是什么?
  • @BenjaminLeinweber 哦,对不起。 :编辑:
  • 出于好奇,你在哪里看到的size_t不保证是一样的?

标签: c memory kernel kernel-module


【解决方案1】:

看了一会,好像size_t有点怪怪的。 This post 引用维基百科(虽然看起来引用的文本不再存在)说size_t 是通过stddef.hstdlib.h 中定义的。我检查了我的 Ubuntu 12.04 安装,确实:

/* Get size_t, wchar_t and NULL from <stddef.h>.  */
#define     __need_size_t
#ifndef __need_malloc_and_calloc
# define    __need_wchar_t
# define    __need_NULL
#endif

stddef.h文件比较复杂,这里就不引用了,不过typedef __SIZE_TYPE__ size_t好像也是外部定义的。我没有进一步追溯它,因为它变得很粘。

最后,我认为size_t 应该在给定架构中保持一致,无论是内核还是 glibc。

在我的 32 位 Ubuntu 安装中,sizeof(size_t) 始终返回 4,无论是来自用户应用程序还是来自 hello world 内核可加载模块。

【讨论】:

  • 好的,我将重新测试我的代码,但前几次测试返回的值不同(不是size_t 的大小,而是我序列化-反序列化时得到的值)。你发现我的代码有问题吗?
  • 您的代码没有显示您的用户空间如何将数据传递到内核空间。我知道可能会发生什么,但我需要先看看。
  • 我正在通过 netlink 发送数据。 Netlink 收到一个长度和一个指向内存块的指针。在用户端,块被传递给回调函数。我假设 mem 块被正确传递。
  • 嗯...我通常使用 IOCTL,而不是 netlink,所以我不太熟悉。您发送的数据大小不是 netlink 接口的一部分吗?
  • 是的,确实如此。我必须对 netlink 说“看,我给你一个指向一块大小为 X 的内存块的指针,把它发送到用户空间”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多