我有一个程序,它使用 MAP_FIXED
以 TASK_SIZE - PAGE_SIZE
映射更高地址的内存。
如果我执行该程序,它运行良好,但如果我使用 gdb
运行它,它会在 mmap
之后出现段错误。同样在这一点上,gdb 状态似乎已完全损坏,并且执行似乎到达了一个充满 0
的地址范围(可能来自刚刚创建的新映射)。
gdb
在运行过程中是否使用这个地址范围?我是否清除了一些 gdb 的状态?这个地址范围是否记录在某处?
下面是我对mmap
的调用和地址计算——
#define TASK_SIZE64 (0x800000000000UL - 4096)
#define TASK_SIZE TASK_SIZE64
#define PAGE_OFFSET (void*)TASK_SIZE
...
char *load_address = PAGE_OFFSET - file_size_aligned;
if(load_address != mmap(load_address, file_size_aligned, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)){
err("Failed to allocate memory for raw_binary with: %d\n", errno);
return -1;
}
file_size_aligned
达到 PAGE_SIZE
。这是分配之一。还有一个从 load_address 开始并向后分配更多页面(仅使用 PROT_READ
和 PROT_WRITE
)。
最佳答案
Does gdb use this address range in the running process?
没有。
Have I cleared out some of gdb's state?
没有。
Is this address range documented somewhere?
可能在内核源代码中。
您的程序对可用地址空间做出了无效的假设,并且在关闭 ASLR(GDB 默认情况下)的情况下运行时“自毁”。
您可以通过在 GDB 之外运行您的程序来确认这一点,但禁用 ASLR。它也应该崩溃。尝试其中之一:
# echo 0 > /proc/sys/kernel/randomize_va_space
或
setarch $(uname -m) -R /path/to/exe
如果启用 ASLR,您还可以确认您的程序将在 GDB 下运行:
gdb /path/to/exe
(gdb) set disable-randomization off
(gdb) run
关于c - gdb 保留的地址范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53465930/