相关疑难解决方法(0)

当我们在C中取消引用NULL指针时,操作系统会发生什么?

假设有一个指针,我们用NULL初始化它.

int* ptr = NULL;
*ptr = 10;
Run Code Online (Sandbox Code Playgroud)

现在,程序将崩溃,因为ptr没有指向任何地址,我们正在为其分配一个值,这是一个无效的访问.那么,问题是,操作系统内部会发生什么?是否发生页面错误/分段错误?内核甚至会在页面表中搜索吗?或者崩溃发生在那之前?

我知道我不会在任何程序中做这样的事情,但这只是为了知道在这种情况下OS或编译器内部发生了什么.这不是一个重复的问题.

c null operating-system pointers

41
推荐指数
2
解决办法
2万
查看次数

为什么在x86_64 ABI中选择地址0x400000作为文本段的开头?

文件中.27它说文本段从0x400000开始.为什么选择这个特定的地址?有什么理由吗?相同的地址被选择在GNU ldLinux:

$ ld -verbose | grep -i text-segment
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
Run Code Online (Sandbox Code Playgroud)

这是令人惊讶的,因为这个地址在32位x86可执行文件中更大:

$ ld -verbose | grep -i text-segment
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
Run Code Online (Sandbox Code Playgroud)

我读了这个问题,讨论为什么为i386选择了0x080xxxxx地址,但它没有解释x86_64的变化.在这个问题上很难找到任何解释.有人有线索吗?

linux memory x86-64 elf abi

32
推荐指数
1
解决办法
2259
查看次数

为什么linux二进制文件的虚拟内存地址从0x8048000开始?

在Ubuntu x86系统上反汇编ELF二进制文件我不禁注意到代码(.text)部分从虚拟地址0x8048000开始,所有较低的内存地址似乎都未使用.

这似乎相当浪费,所有谷歌出现都是涉及STACK_TOP的民间传说或防止空指针解除引用.后一种情况看起来可以通过使用单个页面来修复,而不是留下128MB的间隙.

所以我的问题是 - 对于为什么布局已经固定到这些值或者它只是一个随意的选择,有一个确定的答案吗?

linux x86 elf memory-layout

30
推荐指数
1
解决办法
4000
查看次数

为什么ELF入口点0x8048000不能通过"ld -e"选项更改?

跟进为什么ELF执行入口点虚拟地址为0x80xxxxx而不是0x0?为什么Linux程序的虚拟内存地址为0x8048000开始?,为什么我不能ld使用与默认值不同的入口点ld -e

如果我这样做,我会得到一个segmentation fault返回代码139,即使对于默认入口点附近的地址.为什么?

编辑:

我会更具体地提出这个问题:

        .text
        .globl _start    
_start:
        movl   $0x4,%eax        # eax = code for 'write' system call   
        movl   $1,%ebx          # ebx = file descriptor to standard output
        movl   $message,%ecx    # ecx = pointer to the message
        movl   $13,%edx         # edx = length of the message
        int    $0x80            # make the system call
        movl   $0x0,%ebx        # the status returned by 'exit'
        movl   $0x1,%eax        # eax = code for …
Run Code Online (Sandbox Code Playgroud)

linker elf memory-layout

10
推荐指数
1
解决办法
7295
查看次数

在ELF文件中,如何确定_start的地址?

我一直在阅读ELF规范,无法确定程序入口点和_start地址从何而来。

似乎它们应该在一个相当一致的位置,但是我编写了一些琐碎的程序,而_start始终在另一个位置。

谁能澄清?

symbols elf

6
推荐指数
1
解决办法
2380
查看次数

指针是否保证>某个值?

在C++中,当我这样做new(甚至是malloc)时,是否可以保证返回地址大于某个值?因为......在这个项目中,我发现使用0-1k作为枚举是非常有用的.但如果有可能获得低价值,我不想这样做.我唯一的目标系统是带有OS窗口/ linux和mac的32或64位CPU.

标准是否对指针有所说明?Windows或Linux是否会说出他们的C运行时以及最低内存地址(对于ram)是什么?

-edit-我最终修改我的new重载以检查地址是否高于> 1k.如果没有,我调用std :: terminate.

c++ memory ram pointers new-operator

5
推荐指数
2
解决办法
647
查看次数

为什么在将ELF的虚拟地址映射到虚拟空间之前就可以确定它?

链接目标文件以生成ELF文件,并确定其虚拟地址。例如,.text的虚拟地址为0x8048000。当ELF文件要映射到虚拟空间时,另一个ELF已经映射到该地址。操作系统应该做什么?为什么在将ELF的虚拟地址映射到虚拟空间之前就可以确定它的原因。

linux operating-system elf linux-kernel

5
推荐指数
1
解决办法
309
查看次数

为什么 ELF 可执行文件有一个固定的加载地址?

ELF 可执行文件有一个固定的加载地址(32 位 x86 Linux 二进制文件为 0x804800,64 位 x86_64 二进制文件为 0x40000)。

我阅读了关于这些特定地址的历史原因的 SO 答案(例如,this one)。我仍然不明白的是为什么要使用固定的加载地址而不是随机的地址(给定一些范围内要随机化)?

linker compilation elf

5
推荐指数
2
解决办法
1920
查看次数