【问题标题】:The program executable file marked as read-only标记为只读的程序可执行文件
【发布时间】:2012-05-06 18:59:11
【问题描述】:

我正在阅读有关分段错误的维基百科,并通过以下代码和语句获得。

int main(void)
 {
     char *s = "hello world";
     *s = 'H';
 }

当包含这段代码的程序被编译时,字符串“hello world”被放置在程序可执行文件标记的部分 只读;加载时,操作系统将其与其他 只读内存段中的字符串和常量数据。什么时候 执行后,变量 s 被设置为指向字符串的位置,并且 尝试通过变量将 H 字符写入 内存,导致分段错误。编译这样的程序 使用不检查只读分配的编译器 编译时的位置。

我的问题是关于文件权限,即当可执行文件标记为只读以及何时读写 等等?

我想了解所有关于文件权限的信息。我们可以显式更改文件权限吗?

【问题讨论】:

  • 当它说文件的时候,是不是意味着堆栈在这里?
  • 正在运行的程序中的文件访问权限和内存访问权限不相关。将可执行程序标记为可写不会导致其文本页面被映射为读/写;相反,将其标记为只读不会导致其数据页意外地映射为只读。
  • 我不确定文件权限的相关性——维基文章指的是内存页的权限。可以以特定于系统的方式更改页面权限,例如 POSIX 系统上的mprotect()
  • 这里的文件是可执行文件。

标签: c segmentation-fault file-permissions


【解决方案1】:

“hello world”存储在内存的只读部分。写入可执行文件内存的给定部分的能力与写入磁盘上的可执行文件的能力无关。

【讨论】:

  • 并非所有可执行文件的内存都是只读的。例如,如果你有i=0; i=2 之类的东西,那么i 将存储在读写内存中(假设编译器没有将其优化为一个赋值)。
  • @IndieProgrammer 默认情况下是的。它是可执行文件中可加载段的属性;默认情况下,文本(= 代码)段被标记为只读,但您可以覆盖它。只读段的优点不仅在于防止错误代码,还在于它们可以更轻松地在多个运行实例的内存映像之间共享。
  • 感谢 '@geekosaur' 和 '@Patrick' 对该主题的精彩看法。
【解决方案2】:

您在这个问题中讨论了 3 个不相关的概念:

  • 文件属性(某些操作系统支持,例如 Windows)- 其中之一是只读的。管理文件的正常打开方式,具有修改文件权限的用户可以随意更改文件属性。
  • 文件权限(大多数操作系统支持)。如果给定的用户有权访问/修改,并且在某些系统中执行该文件。
  • 内存页上的内存保护属性。大多数实现虚拟内存的操作系统都支持。内存的每一页(即 4Kb 块)都有一组属性(即读、写、执行),这些属性由操作系统的内存管理部分与 CPU 一起设置和执行。大多数现代 CPU 直接使用此页面属性来验证内存操作。

即在 Windows 上,您可以使用 VirtualProtect 函数指定在程序地址空间中分配的给定内存块应具有的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    相关资源
    最近更新 更多