68 votes

Comment déboguer les programmes Rust ?

Comment déboguer les programmes Rust ?

72voto

artella Points 1312

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 :

20voto

quux00 Points 2496

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X