【问题标题】:Segmentation fault in 64-bit AMD64 mode64 位 AMD64 模式下的分段错误
【发布时间】:2014-10-31 20:42:06
【问题描述】:

我试图理解以下悖论:

我在 64 位 Linux 中运行程序。所以程序运行在 64 位模式(AMD64 长模式的子模式),对吧? 但是这种模式没有分段,只有分页。那为什么下面的代码会产生分段错误呢?

int main() {
  int* ptr = (int*)0xABCDABCDABCD;
  *ptr = 10;
  return 0;
}

【问题讨论】:

  • 此地址可能位于标记为只读的页面中。因此尝试通过以下方式更改该页面中的任何内容: *ptr = 10;将引发故障,通常是 seg 故障。

标签: c segmentation-fault 64-bit


【解决方案1】:

称为分段错误,与底层分页技术无关。这意味着(通常)您试图访问超出允许范围(您的段)的内存,它可能被称为块、块、部分、memlim、xyzzy、plugh 或 any em> 真的。

这与你在 Java 中得到一个空 pointer 异常时的情况大致相同,尽管语言中没有“指针”:-)

在 UNIX (SIGSEGV) 中指示它的信号早在 Intel 为我们提供原始 x86 芯片的分段架构之前就已经存在了。

【讨论】:

  • 所以这是页面错误?但是页面错误导致操作系统将页面加载到物理内存......
  • @matheuscscp,同样,分页是底层技术,甚至可能不存在(它可能用于后来的 x86 芯片)。并且操作系统很可能会出现页面错误并尝试引入页面,当它发现您有 no 此类页面要为您的进程地址空间加载时,它可能会出现段错误。例如,操作系统为您提供 4M 地址空间,而您尝试写入高于该空间的内容:操作系统页面错误,发现它超出了您的范围并在任何(真正)坏事发生之前阻止您。或者您在虚拟地址空间中写入 3G 行上方的操作系统内存,并且它是写保护的。等等……
  • 好的,但是系统如何知道虚拟地址 0xABCDABCDABCD 超出范围,因为每个进程都有自己的完整 64 位虚拟寻址空间?
  • 是不是因为页表中没有虚拟地址0xABCDABCDABCD的页条目?
  • @matheuscscp:很有可能,是的。每个进程都可能拥有完整的虚拟地址范围,但这并不意味着它们已经将物理内存映射到这些地址中的每一个之后。参见例如stackoverflow.com/questions/9006634/…
猜你喜欢
  • 2014-02-28
  • 2013-02-25
  • 2015-10-16
  • 2022-12-18
  • 2023-01-11
  • 2011-12-13
  • 2021-07-28
  • 1970-01-01
  • 2016-09-10
相关资源
最近更新 更多