如何调试生锈的板条箱

Min*_*Zha 12 rust

我正在写一个新的箱子.我为它编写了一些测试并运行测试cargo test.之后,在target文件夹中生成一些test_xxx可执行文件.我启用了调试选项Cargo.toml.通过运行gdb targets/test_xxx,我可以列出并调试test_xxx文件中的代码.但是,我无法进入箱子里的功能.没有调试信息.如何构建/链接包以包含其调试信息?

跟进

我做了更多的研究,发现我的原始问题是不准确的.它不会发生在外部包中的所有方法中,而只会发生在那些通用方法中.我提交了一个详细步骤的问题:https://github.com/rust-lang/rust/issues/19228.请在那里阅读评论.

这是我正在做的调试泛型方法:

  1. 像往常一样在test文件夹中写测试.运行"货物测试"以检查是否成功.
  2. 如果失败,我将测试代码移动到crate lib.rs文件中,并使用"rustc -g src/lib.rs"构建二进制文件.
  3. 使用gdb调试lib.

She*_*ter 8

你的问题有点模糊,所以我会描述我做了什么:

创建一个新箱子:

cargo new so
cd so/
Run Code Online (Sandbox Code Playgroud)

添加一小段代码:

// src/lib.rs

fn thing1(a: int) -> int {
    a + 2
}

fn thing2(a: int) -> int {
    a * a
}

pub fn do_a_thing(a: int, b: int) -> int {
    thing2(b) - thing1(a)
}
Run Code Online (Sandbox Code Playgroud)

创建了一个外部测试; 一个住在里面的人tests.这符合您的评论test_XXX,我猜是最好的:

// tests/alpha.rs

extern crate so;

#[test]
fn it_works() {
    assert_eq!(1, so::do_a_thing(1, 2))
}
Run Code Online (Sandbox Code Playgroud)

运行测试:

$ cargo test
     Running target/alpha-e0c6f11f426d14d2

running 1 test
test it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Run Code Online (Sandbox Code Playgroud)

在我的调试器中打开它:

$ lldb target/alpha-e0c6f11f426d14d2
Run Code Online (Sandbox Code Playgroud)

在包中的方法上设置断点并运行它:

(lldb) br set -r 'do_a_thing'
Breakpoint 1: where = alpha-e0c6f11f426d14d2`so::do_a_thing + 53 at lib.rs:10, address = 0x00000001000629f5
(lldb) r
Process 16843 launched: '/private/tmp/so/target/alpha-e0c6f11f426d14d2' (x86_64)

running 1 test
Process 16843 stopped
* thread #2: tid = 0x774ee, 0x00000001000629f5 alpha-e0c6f11f426d14d2`so::do_a_thing(a=1, b=2) + 53 at lib.rs:10, stop reason = breakpoint 1.1
    frame #0: 0x00000001000629f5 alpha-e0c6f11f426d14d2`so::do_a_thing(a=1, b=2) + 53 at lib.rs:10
   7    }
   8
   9    pub fn do_a_thing(a: int, b: int) -> int {
-> 10       thing2(b) - thing1(a)
   11   }
(lldb) p b
(long) $0 = 2
(lldb) p a
(long) $1 = 1
(lldb) br set -r 'thing2'
Breakpoint 2: where = alpha-e0c6f11f426d14d2`so::thing2 + 46 at lib.rs:6, address = 0x00000001000629ae
(lldb) c
Process 16843 resuming
Process 16843 stopped
* thread #2: tid = 0x774ee, 0x00000001000629ae alpha-e0c6f11f426d14d2`so::thing2(a=2) + 46 at lib.rs:6, stop reason = breakpoint 2.1
    frame #0: 0x00000001000629ae alpha-e0c6f11f426d14d2`so::thing2(a=2) + 46 at lib.rs:6
   3    }
   4
   5    fn thing2(a: int) -> int {
-> 6        a * a
   7    }
   8
   9    pub fn do_a_thing(a: int, b: int) -> int {
(lldb) p a
(long) $2 = 2
Run Code Online (Sandbox Code Playgroud)

这表明我能够在箱子中设置断点和调试.

编辑关于依赖板条箱的后续评论:

我把它添加到我的Cargo.toml:

[dependencies]

time = "~0.1.0"
Run Code Online (Sandbox Code Playgroud)

随着这段代码:

// src/lib.rs

extern crate time;

pub fn do_another_thing() -> bool {
    time::precise_time_ns() % 2 == 0
}
Run Code Online (Sandbox Code Playgroud)

而这个测试(仍在外部测试文件中):

// tests/alpha.rs

#[test]
fn it_works2() {
    assert_eq!(true, so::do_another_thing())
}
Run Code Online (Sandbox Code Playgroud)

像以前一样构建并运行测试,然后像以前一样在调试器中打开它:

(lldb) br set -r 'precise_time'
Breakpoint 1: 4 locations.
(lldb) r
Process 17279 launched: '/private/tmp/so/target/alpha-e0c6f11f426d14d2' (x86_64)

running 2 tests
test it_works ... ok
Process 17279 stopped
* thread #2: tid = 0x799a1, 0x00000001000052c9 alpha-e0c6f11f426d14d2`time::precise_time_ns + 41 at lib.rs:173, stop reason = breakpoint 1.2
    frame #0: 0x00000001000052c9 alpha-e0c6f11f426d14d2`time::precise_time_ns + 41 at lib.rs:173
   170   * in nanoseconds since an unspecified epoch.
   171   */
   172  pub fn precise_time_ns() -> u64 {
-> 173      return os_precise_time_ns();
   174
   175      #[cfg(windows)]
   176      fn os_precise_time_ns() -> u64 {
Run Code Online (Sandbox Code Playgroud)

使用GDB代替LLDB

你也可以使用GDB,但看起来可能有点困难.在主包的代码中设置断点后,我介入并看到函数名称似乎是错误的版本.您可以将其用作断点.

注意我的正则表达式断点不能按预期工作,还要注意实际断点的行号:

(gdb) rbreak precise_time_ns
u64 _ZN4time15precise_time_nsE()();
static u64 _ZN4time15precise_time_ns18os_precise_time_nsE()();
Breakpoint 1 ('_ZN4time15precise_time_ns18os_precise_time_ns13closure.24322E') pending.
<function, no debug info> time::precise_time_ns::os_precise_time_ns::closure.24322;

(gdb) b _ZN4time15precise_time_nsE
Breakpoint 2 at 0x1000052a0: file lib.rs, line 172.

(gdb) r
Starting program: /private/tmp/so/target/alpha-e0c6f11f426d14d2

running 2 tests
test it_works ... ok
[Switching to process 49131 thread 0xd03]

Breakpoint 1, _ZN4time15precise_time_nsE () at lib.rs:172
172 pub fn precise_time_ns() -> u64 {
(gdb) list
167
168 /**
169  * Returns the current value of a high-resolution performance counter
170  * in nanoseconds since an unspecified epoch.
171  */
172 pub fn precise_time_ns() -> u64 {
173     return os_precise_time_ns();
174
175     #[cfg(windows)]
176     fn os_precise_time_ns() -> u64 {
Run Code Online (Sandbox Code Playgroud)