如何调试生锈的板条箱

时间:2014-11-20 05:16:25

标签: rust

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

跟进

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

我正在调试泛型方法:

  1. 照常将测试写入tests文件夹中。运行“货物测试”以检查是否成功。
  2. 如果失败,我将测试代码移到crate lib.rs文件中,并使用“rustc -g src / lib.rs”构建二进制文件。
  3. 使用gdb调试lib

2 个答案:

答案 0 :(得分:8)

你的问题有点模糊,所以我会描述我的所作所为:

创建一个新的包:

cargo new so
cd so/

添加一小段代码:

// 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)
}

创建外部测试;一个住在tests的人。这符合您对test_XXX的评论,我认为最好:

// tests/alpha.rs

extern crate so;

#[test]
fn it_works() {
    assert_eq!(1, so::do_a_thing(1, 2))
}

运行测试:

$ cargo test
     Running target/alpha-e0c6f11f426d14d2

running 1 test
test it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

在我的调试器中打开它:

$ lldb target/alpha-e0c6f11f426d14d2

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

(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

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

编辑有关相关包装箱的后续评论:

我将此添加到我的Cargo.toml

[dependencies]

time = "~0.1.0"

此代码:

// src/lib.rs

extern crate time;

pub fn do_another_thing() -> bool {
    time::precise_time_ns() % 2 == 0
}

此测试(仍在外部测试文件中):

// tests/alpha.rs

#[test]
fn it_works2() {
    assert_eq!(true, so::do_another_thing())
}

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

(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 {

使用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 {

答案 1 :(得分:0)

在收到答案后,我发现外部包装箱中的所有方法都不会发生这种情况,只有通用方法会发生这种情况。我向issue 19228提交了详细步骤。

这是我在调试通用方法的同时所做的事情:

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