Comment déboguer les programmes Rust ?
Réponses
Trop de publicités?On doit compiler en utilisant le -g
drapeau. Supposons donc que l'on dispose du programme ( prog1.rs ) :
//prog1.rs
extern crate rand;
use rand::{task_rng, Rng};
fn main() {
let names = ["Alice", "Bob", "Carol"];
for name in names.iter() {
let v = task_rng().shuffle(~[1,2,3]);
for num in v.iter() {
println!("{:s} says: {:d}", *name, *num);
}
}
}
Compile via :
rustc -g prog1.rs
Cela crée un exécutable appelé prog1 . Le débogage sur cet exécutable est initié par la commande :
gdb ./prog1
On peut alors placer un point d'arrêt sur le shuffle
de la manière suivante :
(gdb) rbreak shuffle
Le programme est ensuite exécuté en tapant run
à l'invite de gdb comme suit :
(gdb) run
et gdb aurait dû s'arrêter au point d'arrêt.
Références :
Pour compléter la réponse de @artella ci-dessus, j'ai écrit un article de blog qui montre une session de débogage gdb d'un code Rust qui implique des fonctions nommées et des fermetures anonymes : http://thornydev.blogspot.com/2014/01/debugging-rust-with-gdb.html
Je vais souligner certains détails ici.
Cet exemple a été mis à jour pour Rust v0.11pre. J'ai deux fichiers de code :
quux.rs :
pub fn quux00(x: || -> int) -> int {
println("DEBUG 123");
x()
}
et bar.rs
extern crate quux;
fn main() {
{
let x = || {
7 + y
};
let retval = quux::quux00(x);
println!("retval: {:?}", retval);
}
y = 5;
println!("y : {:?}", y);
}
Compilez-les avec les informations de débogage incluses :
$ rustc -g --crate-type lib quux.rs
$ rustc -g -L . bar.rs
Commencez le bar
dans gdb et mettons quelques points d'arrêt :
$ gdb bar
(gdb) break bar::main
Breakpoint 1 at 0x4042c0: file bar.rs, line 3.
(gdb) rbreak quux00
Breakpoint 2 at 0x43e760: file quux.rs, line 1.
int quux::quux00(int ())(int ());
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004042c0 in bar::main at bar.rs:3
2 breakpoint keep y 0x000000000043e760 in quux::quux00 at quux.rs:1
Je peux utiliser break
sur les fonctions dans le fichier "principal", puisque le chemin est conservé, mais pour la fonction dans le fichier non principal, j'ai trouvé qu'il est plus facile d'utiliser rbreak
qui prend une expression régulière, comme @artella l'a mentionné ci-dessus.
À partir de là, vous pouvez lancer le programme, puis activer les points d'arrêt et examiner le code comme vous le faites habituellement avec gdb (voir l'article du blog pour un exemple).
Une autre note intéressante - rbreak
peut prendre une expression régulière qui est limitée à un fichier spécifique avec rbreak <file>:<regex>
notation. J'ai découvert que lorsque je fais cela, cela va également placer un point d'arrêt sur la fermeture anonyme que j'ai créée dans le fichier bar.rs
:
(gdb) rbreak bar.rs:.
Breakpoint 1 at 0x403bc0: file bar.rs, line 3.
static void bar::main();
Breakpoint 2 at 0x403e20: file bar.rs, line 5.
static int fn1356()();
Le site fn1356
se réfère à cette fermeture :
let x = || {
7 + y
};
dans la méthode principale.