Windows10 Ubuntu子系统中Rust调试遇gdb断点插入失败问题
在Windows 10的Ubuntu子系统(WSL)中调试Rust程序,cargo build编译正常,程序运行可输出结果17,但用gdb调试时出现异常:设置断点break main.rs:2后执行run,提示无法插入断点、无法访问内存地址0x8007b17,同时出现opening /proc/PID/mem file for lwp 3261.3261 failed的警告。已尝试WSL相关issue中的方法但无效,寻求解决办法。
调试的main.rs代码:
1 fn main() { 2 let a = 2; 3 let result = stack_only(a); 4 dbg!(result); 5 } 6 7 fn stack_only(b: i32) -> i32 { 8 let c = 3; 9 return b + c + stack_and_heap(); 10 } 11 12 fn stack_and_heap() -> i32 { 13 let d = 5; 14 let e = Box::new(7); 15 return d + *e; 16 }
gdb操作日志:
(gdb) list 1 fn main() { 2 let a = 2; 3 let result = stack_only(a); 4 dbg!(result); 5 } 6 7 fn stack_only(b: i32) -> i32 { 8 let c = 3; 9 return b + c + stack_and_heap(); 10 } (gdb) break main.rs:2 Breakpoint 1 at 0x7b17: file src/main.rs, line 2. (gdb) run Starting program: /home/tembolo381/Rust-Workspace/rust_test/target/debug/rust_test warning: opening /proc/PID/mem file for lwp 3261.3261 failed: No such file or directory (2) Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x8007b17
解决办法
编译时保留完整调试信息并关闭地址随机化
执行以下命令编译程序,确保生成完整调试符号并禁用地址空间布局随机化(ASLR):RUSTFLAGS="-C debuginfo=full -C relocation-model=static" cargo build这能避免因ASLR导致的内存地址偏移问题,是WSL中gdb调试的常见触发点。
切换到WSL2版本
WSL1的内存虚拟化机制更容易引发这类问题,先查看当前WSL版本:wsl -l -v若目标发行版是WSL1,执行命令切换为WSL2:
wsl --set-version <发行版名称> 2切换完成后重启WSL。
更新gdb到最新版本
WSL自带的gdb版本可能存在兼容性问题,执行更新:sudo apt update && sudo apt install --upgrade gdb更新后重新尝试调试。
关闭WSL2内核内存页随机化
在Windows的%USERPROFILE%\.wslconfig文件中添加以下配置(文件不存在则新建):[wsl2] kernelCommandLine = page_alloc.shuffle=0执行
wsl --shutdown关闭WSL后重启,该配置可避免内核随机化内存页导致gdb定位地址错误。使用rust-gdb替代原生gdb
Rust官方提供的rust-gdb针对Rust程序做了调试适配,直接执行:rust-gdb target/debug/rust_test进入调试后再设置断点运行,大概率能规避原生gdb的兼容性问题。
内容的提问来源于stack exchange,提问作者tembolo1284

