x86_64 Linux下获取rbp寄存器值并解引用触发栈溢出问题咨询
Rust读取rbp寄存器触发栈溢出的原因分析
问题代码
use std::arch::asm; fn print_call_stack() { let mut fp: u64; unsafe { asm!( "mov {}, rbp", out(reg) fp, ) }; println!("{:#x}", fp); let raw = fp as *mut u64; fp = unsafe { raw.read_volatile() }; println!("{:#x}", fp); } fn main() { print_call_stack(); }
运行错误信息
thread 'main' has overflowed its stack fatal runtime error: stack overflow [1] 15344 IOT instruction (core dumped) cargo run
问题解答
你的猜测不正确,错误的核心原因是Rust默认启用了栈帧指针消除优化,具体细节如下:
- x86_64 Linux环境下,Rust编译器默认会开启帧指针消除(Frame Pointer Elimination)优化。开启该优化后,rbp寄存器不再承担传统的栈帧基指针角色,而是被当作普通通用寄存器来使用,此时你读取到的rbp值并不是栈帧的起始地址,而是一个随机的、无意义的寄存器值。
- 当你把这个无意义的数值强制转换为
*mut u64指针并尝试解引用时,实际上是在访问非法的内存区域,这种非法内存访问会触发段错误,但Rust运行时将其误报为"栈溢出"。 - 如果要验证这个结论,可以在编译时禁用帧指针消除优化,通过添加编译参数
-C force-frame-pointers=yes来强制保留rbp的栈帧指针功能。此时重新运行代码,就能正确读取上一级栈帧的rbp值,不会触发崩溃。
内容的提问来源于stack exchange,提问作者Dlwlrma1605
相关产品推荐
相关产品推荐

