本文介绍工具 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 调试入门指北相关推荐

  1. Python 简单入门指北(试读版)

    本文是我小专栏中 Python 简单入门指北 一文的前半部分,如果你能坚持读完并且觉得有一定收获,建议阅读原文,只需一杯咖啡钱就可以阅读更精彩的部分,也可以订阅小专栏或者加入我的知识星球,价格都是 6 ...

  2. TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧

    首发于TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧!,最新回复以及交流请看这里~ 推荐一个深蓝学院的CUDA课程,TensorRT_Tutorial的作者伟哥讲解的,质量很 ...

  3. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  4. Flutter 入门指北(Part 9)之弹窗和提示(SnackBar、BottomSheet、Dialog)

    该文已授权公众号 「码个蛋」,转载请指明出处 前面的小节把常用的一些部件都介绍了,这节介绍下 Flutter 中的一些操作提示.Flutter 中的操作提示主要有这么几种 SnackBar.Botto ...

  5. 计算机学习入门指北——计科软工网络信安侧重图析、解读专业术语、岗位分类、未来规划

    申明:本博文偏技术向,主观性较强,其中部分理解必有偏差和误解,望指出改正! 计算机学习入门指北: 作为刚入学的计算机系学生,面对一片专业术语十分蒙.区块链?大数据?开源?数据库?嵌入式开发?前端后端? ...

  6. 【杭电数电实验】verilog入门指北

    verilog入门指北 前言 指北内容 面向人群 基础实验 1-15 代码参考 正文 ISE 的安装 实验的基本操作流程 可能出现的问题 创建工程闪退 希望删除某一文件,实际上并没有删除 如何编写测试 ...

  7. 萌妹子Python入门指北(二)

    原文来自 (ixindoo.com)[http://ixindoo.com/articles/662] 只写了第一篇就好久没更新了,为啥?因为妹子学编程的意愿不强了,我也不能逼迫她去学.不过后来收到部 ...

  8. 【Linux入门指北】第一篇 初识Linux

    目录 前言 一.Linux操作系统的发展历史 1.Linux操作系统的诞生 2.Linux操作系统的发展 1.自由软件基金会(FSF) 2.GPL协议 3.GUN工程 二.Linux的不同发行版本 1 ...

  9. Android环信3.0即时通讯云入门指北

    Android环信3.0即时通讯云入门指北 官方文档 http://docs-im.easemob.com/im/android/sdk/import 基础集成 http://docs-im.ease ...

  10. unity hub版本管理工具 中文包 及入门指北

    2021/12/19更新 目录 一.环境 二.hub装unity 三.中文包 四.一些事情 五.意外情况 六.hub和unity下载的一些坑 七.入门指北 一.环境 内网环境 win (其它不管) 二 ...

最新文章

  1. typescript调用javascript URI.js
  2. centos下安装VMware Server 虚拟机的方法
  3. cxTreeList交换当前两个节点的的位置
  4. suse linux 查看内存,Suse linux查询内存大小的指令是什么?
  5. java ref 应用类型_Java四种引用类型
  6. DataGridView 控件中至少有一列没有单元格模板的解决
  7. 一种RTP接收和解包的程序
  8. 电脑音响怎么插_BMW宝马5系G38改原厂全套哈曼卡顿音响+无钥匙进入,厚街宝马原厂改装中心...
  9. 强化学习组队学习task02——马尔可夫决策过程及表格型方法
  10. 应对艰难职场环境的五条策略
  11. 二分+贪心——HDU 5855
  12. [IDE]webstorm安装并配置sass踩坑(windwos)
  13. 关于开机USB电涌15秒关机的另类解决方法
  14. 很有哲理的句子,每天都值得看一遍
  15. Spring-AOP 代理,增强
  16. 如何使用gcore工具获取一个core文件而不重启应用?
  17. 就算是假期也全力以赴,学习不能停
  18. css关键词:inherit、initial、overlay、revert、unset解释
  19. 信息系统开发与管理【三】之 系统开发方法概述
  20. 解决mysql同一个用户多个密码的问题---远程密码和本地密码不一致

热门文章

  1. python:修改图片的尺寸
  2. 用几何画板演示高尔顿钉板动画
  3. hdmi接口线_终于有人能把HDMI和VGA的5大区别讲全了,网友:讲得真详细
  4. python 整合excel_使用python将多个excel文件合并到同一个文件的方法
  5. 解决移动端点击响应速度慢的问题tap
  6. 台式电脑怎么组装步骤_台式电脑组装教程图解,手把手教您组装(零基础也能搞定)...
  7. 在遇到移动硬盘无法访问的情况下,如何无需格式化地修复硬盘?
  8. Dell台式计算机BIOS放电,戴尔BIOS设置电池维修笔记本电脑电池BIOS设置图形方法...
  9. Segment Tree Beats(吉司机线段树)
  10. 踏雪点圣火,冰雕刻五环!揭秘全球刷屏的冬奥开幕式黑科技