2014-12-03 58 views
20

所以我有一個失敗的貨運測試:如何在gdb中調試失敗的貨物測試?

$ cargo test 
[snip] 
    Running target/gunzip-c62d8688496249d8 

running 2 tests 
test test_extract_failure ... FAILED 
test test_extract_success ... ok 

failures: 

---- test_extract_failure stdout ---- 
     task 'test_extract_failure' panicked at 'assertion failed: result.is_err()', /home/dhardy/other/flate2-rs/tests/gunzip.rs:19 



failures: 
    test_extract_failure 

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

task '<main>' panicked at 'Some tests failed', /home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libtest/lib.rs:250 

如何啓動失敗的測試在調試器(GDB或相似的)?

這應該是一個普遍的問題,但對於那些想追溯我的步驟,安裝近期夜間鏽構建和:

git clone https://github.com/dhardy/flate2-rs.git 
git checkout 24979640a880 
cd flate2-rs 
cargo test 

回答

21

你可以得到一個測試二進制過濾運行通過傳遞更多的測試對它的論據; Cargo也直接暴露了這一點。因此,cargo test test_extract_failure將運行該特定情況。 (如果你有其他測試恐慌並且預計會失敗,這樣很方便,這樣他們就不會調用我將要提到的rust_panic函數,只留下有問題的呼叫。)

爲了使用gdb ,您需要直接運行測試二進制文件(如果您使用Cargo,它會在子進程中運行,因此gdb不會在其中捕獲恐慌)。貨物有用地告訴你文件名,target/gunzip-c62d8688496249d8。您可以直接與--test運行這使其成爲試運行:

$ target/gunzip-c62d8688496249d8 --test test_extract_failure 
running 1 test 
test test_extract_failure ... FAILED 

failures: 

---- test_extract_failure stdout ---- 
     task 'test_extract_failure' panicked at 'assertion failed: result.is_err()', /home/dhardy/other/flate2-rs/tests/gunzip.rs:19 



failures: 
    test_extract_failure 

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

task '<main>' panicked at 'Some tests failed', /home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libtest/lib.rs:250 

現在用gdb把它掛。有一個方便的功能,您可以插入一個斷點,rust_panic。一旦進入gdb,break rust_panic表示在實際進行展開之前,只要有東西觸發恐慌,它就會暫停。

下面是一個會話最終可能看起來像:

$ gdb target/demo-92d91e26f6ebc557 
… 
Reading symbols from target/demo-92d91e26f6ebc557...done. 
(gdb) break rust_panic 
Breakpoint 1 at 0xccb60 
(gdb) run --test test_extract_failure 
Starting program: /tmp/demo/target/demo-92d91e26f6ebc557 --test test_extract_failure 
warning: Could not load shared library symbols for linux-vdso.so.1. 
Do you need "set solib-search-path" or "set sysroot"? 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/usr/lib/libthread_db.so.1". 

running 1 test 
[New Thread 0x7ffff6ef4700 (LWP 14254)] 
[New Thread 0x7ffff5fff700 (LWP 14255)] 
[Switching to Thread 0x7ffff5fff700 (LWP 14255)] 

Breakpoint 1, 0x0000555555620b60 in rust_panic() 
(gdb) bt 
#0 0x0000555555620b60 in rust_panic() 
#1 0x0000555555621274 in unwind::begin_unwind_inner::hb821324209c8ed246Qc() 
#2 0x000055555556bb6d in unwind::begin_unwind::h7834652822578025936() 
#3 0x000055555556b9fd in demo::do_something() at <std macros>:8 
#4 0x000055555556b98e in demo::test_extract_failure() at src/lib.rs:3 
#5 0x000055555559aa4b in task::TaskBuilder::try_future::closure.8077() 
#6 0x000055555560fd03 in task::TaskBuilder::spawn_internal::closure.30919() 
#7 0x000055555561f672 in task::Task::spawn::closure.5759() 
#8 0x0000555555621cac in rust_try_inner() 
#9 0x0000555555621c96 in rust_try() 
#10 0x000055555561f713 in unwind::try::ha8078a6ae9b50ccepFc() 
#11 0x000055555561f51c in task::Task::run::hdb5fabf381084abafOb() 
#12 0x000055555561f168 in task::Task::spawn::closure.5735() 
#13 0x0000555555620595 in thread::thread_start::h4d73784c295273b3i6b() 
#14 0x00007ffff79c2314 in start_thread() from /usr/lib/libpthread.so.0 
#15 0x00007ffff72e25bd in clone() from /usr/lib/libc.so.6 
(gdb) 

在這種特殊情況下,#0-#2,#5#15噪聲,#3,#4是我們想要的信號。

+4

謝謝,克里斯!但是Cargo仍然在構建flate2庫而沒有調試信息,這意味着我無法進行除測試功能以外的任何調試。如何爲flate2 lib/all庫啓用調試?據我瞭解,Cargo有一個'--release'標誌來打開優化,所以爲什麼默認情況下不打開調試信息? [相關問題](http://stackoverflow.com/questions/27032271/how-to-debug-a-crate-in-rust) – dhardy 2014-12-03 13:31:58