2015-07-07 3 views
3

Для паники RUST_BACKTRACE=1 очень полезен, но он не делает многого для нефатальных ошибок.Как вы отслеживаете источник ошибки?

К примеру, у меня есть некоторый код, который заканчивается

match res { 
    Ok(()) =>(), 
    Err(_) => 
     println_err!("{:?}", res), 
} 

К сожалению, работает в gdb не делает кучу по умолчанию, так как ничего особенного не происходит. (Поведение Ye Olde C++, где необработанное исключение назвали бы abort() и gdb сломается на SIGABORT по умолчанию было очень удобно.)

Далее, поскольку gdb теперь поддерживает обратное выполнение, я думал, что я мог отлаживать его, установив точку останова на println_err линии и реверсирования, пока не найду источник ошибки.

(gdb) reverse-step 
Target multi-thread does not support this command. 

Быстрый поиск показал, я должен сделать что-то вроде

(gdb) set libthread-db-search-path /etc/nonexistent 
(gdb) start 

, но затем я получаю

(gdb) reverse-step 
Target child does not support this command. 

Означает ли это, реверс отладка просто не поддерживается в Rust? Или я делаю что-то неправильно/субоптимально?

Есть ли лучшее решение, чем вручную пройти через каждую функцию, которая отправила ошибку (с try!()), чтобы узнать, откуда она была создана?

Edit: Используя ручной точек останова и перезапуска, я попал в точку, где функция возвращалась, но GDB не может показаться сказать, что возвращаемое значение:

(gdb) finish 
Run till exit from #0 cafs::reader::Reader::read_rawblock (self=0x7fffffffd628, h=Sha256 = {...}) at src/reader.rs:90 
0x00005555556a096b in cafs::reader::Reader::read_blockref_vec (self=0x7fffffffd628, r=Reader = {...}) at src/reader.rs:101 
101    let raw = try!(self.read_rawblock(h)); 
Value returned is $3 = {union Result<collections::vec::Vec<u8>, std::io::error::Error> (struct Reader *, struct Sha256)} 0x0 
(gdb) 

Так, может быть, GDB не будет все, что полезно ...

ответ

1

Если вы хотите иметь stacktraces с Result<T, E>, вы можете создать тип, который делает это: http://phildawes.net/blog/2015/06/17/rust-stacktrace/

+1

Это создаст трассу, где ошибка сначала преобразуется в мой код. Это, безусловно, что-то, но я бы предпочел посмотреть, откуда он появился в библиотеке, которая его создала. Было бы очень приятно, если бы у меня была возможность «gdb», чтобы я мог проверить состояние, а не просто получить обратную линию. – aij

+1

Кстати, подобная альтернатива, которую я видел на Reddit, - это ржавчина. https://github.com/daboross/rust-throw/ – aij

2

Reverse отладки не так просто, как reverse-step. Вы должны остановиться в какой-то момент до сбоя и спросить gdb на record. Затем в какой-то более поздний момент вы можете отменить.

Встроенное средство записи находится на медленной стороне. И он не поддерживает многопоточность. Трудно рекомендовать его за пределами некоторых небольших случаев использования.

Если вы серьезно относитесь к проведению обратной отладки для этой проблемы, позвольте мне порекомендовать rr-project. Это гораздо лучший способ приблизиться к этому.

+0

Учитывая очевидную неспособность GDB понять значения возврата Rust, я думаю, что это уже не путь. Я пытался отлаживать обратную отладку, потому что он работал очень хорошо, когда я использовал его в 'ocamldebug'. – aij

Смежные вопросы