Rust LLDB 调试入门指北
本文介绍工具 LLDB 的初步使用
Rust 会使用 DWARF 格式在 binary 中嵌入调试信息,所以可以使用一些通用的调试工具,比如 GDB 和 LLDB。Rust 提供了 rust-gdb
和 rust-lldb
两个命令用于调试,其相比原生的 gdb
和 lldb
添加了一些方便调试的脚本
下面来初步的了解 rust-lldb
的使用,rustup
会安装 rust-lldb
,但不会安装 lldb
,需要自行安装
LLDB 的命令结构如下
<noun> <verb> [-options [option-value]] [argument [argument...]]
本文所使用的代码如下:
fn binary_search(nums: Vec<i32>, target: i32) -> i32 { let mut size = nums.len();if size == 0 {return -1;}let mut base = 0usize;while size > 1 {let half = size / 2;let mid = base + half;if nums[mid] <= target {base = mid;}size = size - half;}if nums[base] == target {return base as i32;}return -1;
}fn main() { assert_eq!(binary_search(vec![1, 4, 7, 10, 16, 19], 10), 3);
}
cargo build
默认会以 debug 模式进行构建,所以含有用于调试的 symbol,需要注意的是 cargo install
会以 release 模式构建,需要 cargo install --debug
通过 rust-lldb
命令加载可执行文件(或者在 REPL 中通过 file
载入),进入 LLDB 的 REPL。比如
rust-lldb target/debug/<bin-name> first_arg
启动时会显示
(lldb) settings set -- target.run-args "first_arg"
字样,参数会存在 target.run-args
中,可以在 REPL 中重置命令行参数
(lldb) settings set target.run-args "arg1"
(lldb) settings show target.run-args
target.run-args (array of strings) = [0]: "arg1"
(lldb) settings append target.run-args "arg2"
(lldb) settings show target.run-args
target.run-args (array of strings) = [0]: "arg1"[1]: "arg2"
gui
命令可以进入 GUI,可以借助 voltron 获得更改的体验
通过 b
命令来设置断点。b
命令是对于 GDB 中 break
命令的模拟,并不是 LLDB 中的 breakpoint
的 alias。breakpoint set -n <func name>
设置支持补全,breakpoint set -f <文件路径>--line 15
在指定的行设置断点
(lldb) b binary_search
Breakpoint 1: where = b`b::binary_search::hcb6e4fa332e0db67 + 13 at main.rs:2, address = 0x00000000000049bd
(lldb) b
Current breakpoints:
1: name = 'binary_search', locations = 1 1.1: where = b`b::binary_search::hcb6e4fa332e0db67 + 13 at main.rs:2, address = b[0x00000000000049bd], unresolved, hit count = 0 2: name = 'binary_s', locations = 0 (pending)3: name = 'binary_search', locations = 1 3.1: where = b`b::binary_search::hcb6e4fa332e0db67 + 13 at main.rs:2, address = b[0x00000000000049bd], unresolved, hit count = 0
(lldb) breakpoint delete 2
1 breakpoints deleted; 0 breakpoint locations disabled.
通过 r
命令来运行程序
(lldb) r
There is a running process, kill it and restart?: [Y/n] y
Process 12494 launched: '/root/T/b/target/debug/b' (x86_64)
Process 12494 stopped
* thread #1, name = 'b', stop reason = breakpoint 1.1frame #0: 0x00005555555589bd b`b::binary_search::hcb6e4fa332e0db67(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:2 1 fn binary_search(nums: Vec<i32>, target: i32) -> i32 {
-> 2 let mut size = nums.len();34 if size == 0 {5 return -1;6 }7
通过 frame variable
可以看到当前栈中的变量
(lldb) frame variable
(alloc::vec::Vec<int>) nums = vec![1, 4, 7, 10, 16, 19]
(int) target = 10
通过 n
进行单步调试
(lldb) n
Process 20123 stopped
* thread #1, name = 'b', stop reason = step overframe #0: 0x00005555555589df b`b::binary_search::hcb6e4fa332e0db67(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:4 1 fn binary_search(nums: Vec<i32>, target: i32) -> i32 {2 let mut size = nums.len();3
-> 4 if size == 0 {5 return -1;6 }7
(lldb) frame variable
(alloc::vec::Vec<int>) nums = vec![1, 4, 7, 10, 16, 19]
(int) target = 10
(unsigned long) size = 6
这都是模拟的 GDB 的命令族。LLDB 原生的则是
(lldb) thead select id
(lldb) thread step-in // The same as gdb's "step" or "s"
(lldb) thread step-over // The same as gdb's "next" or "n"
(lldb) thread step-out // The same as gdb's "finish" or "f"
在断点处可以设置命令,比如直接打印堆栈
(lldb) breakpoint command add 1
Enter your debugger command(s). Type 'DONE' to end.
> bt
> DONE
也可以直接通过 --command
参数设置
一个小例子,在 half == 3
条件成立的时候打印堆栈信息
(lldb) list main.rs:101011 while size > 1 {12 let half = size / 2;13 let mid = base + half;1415 if nums[mid] <= target {16 base = mid;17 }18 size = size - half;19 }20
(lldb) breakpoint set -c "half == 3" -f main.rs -l 13 -C bt
Breakpoint 1: where = b`b::binary_search::hfce4ad2766a2fe8f + 166 at main.rs:13, address = 0x0000000000004a56
(lldb) r
Process 31253 launched: '/root/T/b/target/debug/b' (x86_64)
(lldb) bt
* thread #1, name = 'b', stop reason = breakpoint 1.1* frame #0: 0x0000555555558a56 b`b::binary_search::hfce4ad2766a2fe8f(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:13 frame #1: 0x0000555555558b90 b`b::main::he42792ea9d7cc77a at main.rs:29frame #2: 0x00005555555582c0 b`std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h36f6beb6917ae1e7 at rt.rs:74 frame #3: 0x0000555555561743 b`std::panicking::try::do_call::h4f8262c35e4e88a2 [inlined] std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h10f59d0290367560 at rt.rs:59 frame #4: 0x0000555555561737 b`std::panicking::try::do_call::h4f8262c35e4e88a2 at panicking.rs:307 frame #5: 0x000055555556ebfa b`__rust_maybe_catch_panic at lib.rs:102frame #6: 0x0000555555562246 b`std::rt::lang_start_internal::ha81f57a8465b4dcb [inlined] std::panicking::try::h8abdfbcaa376c6de at panicking.rs:286 frame #7: 0x000055555556220b b`std::rt::lang_start_internal::ha81f57a8465b4dcb [inlined] std::panic::catch_unwind::hcc1db352380c01f1 at panic.rs:398 frame #8: 0x000055555556220b b`std::rt::lang_start_internal::ha81f57a8465b4dcb at rt.rs:58frame #9: 0x0000555555558299 b`std::rt::lang_start::h1bce8d1d740917a0(main=&0x555555558b30, argc=1, argv=&0x7fffffffe3c8) at rt.rs:74 frame #10: 0x0000555555558f1a b`main + 42frame #11: 0x00007ffff7dc9223 libc.so.6`__libc_start_main + 243frame #12: 0x000055555555817e b`_start + 46Process 31253 stopped
* thread #1, name = 'b', stop reason = breakpoint 1.1frame #0: 0x0000555555558a56 b`b::binary_search::hfce4ad2766a2fe8f(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:13 1011 while size > 1 {12 let half = size / 2;
-> 13 let mid = base + half;1415 if nums[mid] <= target {16 base = mid;
可以通过 watch
来监控变量的变化
(lldb) list main.rs:101011 while size > 1 {12 let half = size / 2;13 let mid = base + half;1415 if nums[mid] <= target {16 base = mid;17 }18 size = size - half;19 }20
(lldb) breakpoint set -f main.rs -l 11
Breakpoint 1: where = b`b::binary_search::hfce4ad2766a2fe8f + 88 at main.rs:11, address = 0x0000000000004a08
(lldb) r
Process 1997 launched: '/root/T/b/target/debug/b' (x86_64)
Process 1997 stopped
* thread #1, name = 'b', stop reason = breakpoint 1.1frame #0: 0x0000555555558a08 b`b::binary_search::hfce4ad2766a2fe8f(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:11 89 let mut base = 0usize;10
-> 11 while size > 1 {12 let half = size / 2;13 let mid = base + half;14
(lldb) watch set var base
Watchpoint created: Watchpoint 1: addr = 0x7fffffffdec0 size = 8 state = enabled type = w declare @ '/root/T/b/src/main.rs:9'watchpoint spec = 'base'new value: 0
(lldb) c
Process 1997 resumingWatchpoint 1 hit:
old value: 0
new value: 3
Process 1997 stopped
* thread #1, name = 'b', stop reason = watchpoint 1frame #0: 0x0000555555558aa8 b`b::binary_search::hfce4ad2766a2fe8f(nums=vec![1, 4, 7, 10, 16, 19], target=10) at main.rs:18 15 if nums[mid] <= target {16 base = mid;17 }
-> 18 size = size - half;19 }2021 if nums[base] == target {
expr
命令可以对表达式求值
lldb) frame variable
(unsigned long) size = 24
(unsigned long) align = 4
(lldb) expr size == 24
(bool) $0 = true
Reference
LLDB Tutorial
Rust LLDB 调试入门指北相关推荐
- Python 简单入门指北(试读版)
本文是我小专栏中 Python 简单入门指北 一文的前半部分,如果你能坚持读完并且觉得有一定收获,建议阅读原文,只需一杯咖啡钱就可以阅读更精彩的部分,也可以订阅小专栏或者加入我的知识星球,价格都是 6 ...
- TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧
首发于TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧!,最新回复以及交流请看这里~ 推荐一个深蓝学院的CUDA课程,TensorRT_Tutorial的作者伟哥讲解的,质量很 ...
- Python 简单入门指北(二)
Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...
- Flutter 入门指北(Part 9)之弹窗和提示(SnackBar、BottomSheet、Dialog)
该文已授权公众号 「码个蛋」,转载请指明出处 前面的小节把常用的一些部件都介绍了,这节介绍下 Flutter 中的一些操作提示.Flutter 中的操作提示主要有这么几种 SnackBar.Botto ...
- 计算机学习入门指北——计科软工网络信安侧重图析、解读专业术语、岗位分类、未来规划
申明:本博文偏技术向,主观性较强,其中部分理解必有偏差和误解,望指出改正! 计算机学习入门指北: 作为刚入学的计算机系学生,面对一片专业术语十分蒙.区块链?大数据?开源?数据库?嵌入式开发?前端后端? ...
- 【杭电数电实验】verilog入门指北
verilog入门指北 前言 指北内容 面向人群 基础实验 1-15 代码参考 正文 ISE 的安装 实验的基本操作流程 可能出现的问题 创建工程闪退 希望删除某一文件,实际上并没有删除 如何编写测试 ...
- 萌妹子Python入门指北(二)
原文来自 (ixindoo.com)[http://ixindoo.com/articles/662] 只写了第一篇就好久没更新了,为啥?因为妹子学编程的意愿不强了,我也不能逼迫她去学.不过后来收到部 ...
- 【Linux入门指北】第一篇 初识Linux
目录 前言 一.Linux操作系统的发展历史 1.Linux操作系统的诞生 2.Linux操作系统的发展 1.自由软件基金会(FSF) 2.GPL协议 3.GUN工程 二.Linux的不同发行版本 1 ...
- Android环信3.0即时通讯云入门指北
Android环信3.0即时通讯云入门指北 官方文档 http://docs-im.easemob.com/im/android/sdk/import 基础集成 http://docs-im.ease ...
- unity hub版本管理工具 中文包 及入门指北
2021/12/19更新 目录 一.环境 二.hub装unity 三.中文包 四.一些事情 五.意外情况 六.hub和unity下载的一些坑 七.入门指北 一.环境 内网环境 win (其它不管) 二 ...
最新文章
- typescript调用javascript URI.js
- centos下安装VMware Server 虚拟机的方法
- cxTreeList交换当前两个节点的的位置
- suse linux 查看内存,Suse linux查询内存大小的指令是什么?
- java ref 应用类型_Java四种引用类型
- DataGridView 控件中至少有一列没有单元格模板的解决
- 一种RTP接收和解包的程序
- 电脑音响怎么插_BMW宝马5系G38改原厂全套哈曼卡顿音响+无钥匙进入,厚街宝马原厂改装中心...
- 强化学习组队学习task02——马尔可夫决策过程及表格型方法
- 应对艰难职场环境的五条策略
- 二分+贪心——HDU 5855
- [IDE]webstorm安装并配置sass踩坑(windwos)
- 关于开机USB电涌15秒关机的另类解决方法
- 很有哲理的句子,每天都值得看一遍
- Spring-AOP 代理,增强
- 如何使用gcore工具获取一个core文件而不重启应用?
- 就算是假期也全力以赴,学习不能停
- css关键词:inherit、initial、overlay、revert、unset解释
- 信息系统开发与管理【三】之 系统开发方法概述
- 解决mysql同一个用户多个密码的问题---远程密码和本地密码不一致
热门文章
- python:修改图片的尺寸
- 用几何画板演示高尔顿钉板动画
- hdmi接口线_终于有人能把HDMI和VGA的5大区别讲全了,网友:讲得真详细
- python 整合excel_使用python将多个excel文件合并到同一个文件的方法
- 解决移动端点击响应速度慢的问题tap
- 台式电脑怎么组装步骤_台式电脑组装教程图解,手把手教您组装(零基础也能搞定)...
- 在遇到移动硬盘无法访问的情况下,如何无需格式化地修复硬盘?
- Dell台式计算机BIOS放电,戴尔BIOS设置电池维修笔记本电脑电池BIOS设置图形方法...
- Segment Tree Beats(吉司机线段树)
- 踏雪点圣火,冰雕刻五环!揭秘全球刷屏的冬奥开幕式黑科技