简短的问题:
是否可以将一个已经 malloc 的缓冲区映射为具有两种访问同一缓冲区的方式(两个指针指向同一物理内存)?或者,是否可以临时移动 malloc 接收到的虚拟内存地址?或者是否可以从虚拟空间中的一个位置指向另一个位置?
背景:
我正在使用DirectFB
一个表面管理和 2D 图形堆肥库。我正在尝试强制执行锁定协议,即锁定表面,仅在锁定时修改内存(指针指向使用 malloc 分配的系统内存),然后解锁表面。
我目前正在尝试追踪一个应用程序中的一个错误,该错误是锁定一个表面,然后存储像素指针并稍后修改表面。这意味着库不知道何时可以安全地读取或写入表面。我正在尝试找到一种方法来检测是否违反了锁定协议。我想要的是一种在进行解锁调用后使传递给用户的指针无效的方法。更好的是,如果应用程序在锁定后尝试访问内存,我希望应用程序能够分段错误。这将在调试器中停止,并让我们了解涉及哪个表面、涉及哪个例程、谁调用了它等。
可能的解决方案:
创建一个临时缓冲区,将缓冲区指针传递给用户,解锁时将像素复制到实际缓冲区,删除临时缓冲区。
- 优点:这是一个可实施的解决方案。
- 缺点:性能很慢,因为它需要一个昂贵的副本,而且内存可能可用也可能不可用。无法保证一个临时表面与另一个表面重叠,从而允许无效的指针突然再次工作。
为 malloc 的表面制作额外的地图并将其传递给用户。解锁时,取消映射内存。
- 优点:非常快,不需要额外的内存。
- 缺点:不知道这是否可能。
- 陷阱:需要留出一个保留的地址范围,不会被其他任何东西(包括 malloc 或内核)使用。还需要确保没有两个表面重叠,这可能允许旧指针突然指向有效的东西,而不是在应该的时候出现段错误。
利用库在被用户锁定时不访问内存这一事实,只需将虚拟地址移动到锁上并在解锁时将其移回。
- 优点:非常快,不需要额外的内存。
- 缺点:不知道这是否可能。
- 陷阱:与上面的“2”相同。
这可行吗?
附加信息:
- 这是 using
Linux 2.6
, using stdlib。- 该库是用
C
.- 库和应用程序在用户空间中运行。
- 有可能使用内核模块(编写自定义内存分配例程),但在我当前的工作环境中编写模块的难度可能会将我实际实现此解决方案的机会降低到接近零的水平。但如果这是唯一的方法,那就太好了。
- 底层处理器是
x86
.