probleme de debugger

Le
espie
J'ai un bout de code qui recupere les exceptions a coup de
eval {.die };
if ($@) {

die # rethrow
}

probleme: comment debugguer tout ca ?

j'aimerais bien que perl -d me montre une stack trace a l'endroit du
premier die
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Paul Gaborit
Le #20434251
À (at) Tue, 27 Oct 2009 12:01:49 +0000 (UTC),
(Marc Espie) écrivait (wrote):
J'ai un bout de code qui recupere les exceptions a coup de
eval {....die ...};
if ($@) {
...
die ... # rethrow
}

probleme: comment debugguer tout ca ?

j'aimerais bien que perl -d me montre une stack trace a l'endroit du
premier die...



Il est encore possible d'utiliser $SIG{__DIE__} pour capter 'die'
(cf. perlvar) même si la documentation dit qu'un jour cette
possibilité n'existera plus dans les 'eval'.

Mais je ne comprends pas le besoin... Pourquoi ne pas instrumenter
l'appel à 'die' lui-même en lui passant une référence comme argument
(cf. perldoc -f die) ? Dans cette référence on peut stocker toute
l'information nécessaire...

--
Paul Gaborit - Perl en français -
espie
Le #20436401
In article Paul Gaborit

À (at) Tue, 27 Oct 2009 12:01:49 +0000 (UTC),
(Marc Espie) écrivait (wrote):
J'ai un bout de code qui recupere les exceptions a coup de
eval {....die ...};
if ($@) {
...
die ... # rethrow
}

probleme: comment debugguer tout ca ?

j'aimerais bien que perl -d me montre une stack trace a l'endroit du
premier die...



Il est encore possible d'utiliser $SIG{__DIE__} pour capter 'die'
(cf. perlvar) même si la documentation dit qu'un jour cette
possibilité n'existera plus dans les 'eval'.

Mais je ne comprends pas le besoin... Pourquoi ne pas instrumenter
l'appel à 'die' lui-même en lui passant une référence comme argument
(cf. perldoc -f die) ? Dans cette référence on peut stocker toute
l'information nécessaire...



En fait, j'ai ete un peu vite en description... ce qui m'interesse, c'est
un cas ou ce n'est pas moi qui suis a l'origine du die. En l'occurrence,
un $object->method avec $object qui vaut undef...

Et perl -d me donne un backtrace... du 2e die. Et j'aimerais non pas capter
die, mais pouvoir dire "si debugguer, alors tu me fais un backtrace dans
l'eval, PUIS tu recuperes l'exception, puis tu continues" et je ne vois
pas trop comment faire...
Paul Gaborit
Le #20437991
À (at) Tue, 27 Oct 2009 18:36:21 +0000 (UTC),
(Marc Espie) écrivait (wrote):
In article Paul Gaborit

À (at) Tue, 27 Oct 2009 12:01:49 +0000 (UTC),
(Marc Espie) écrivait (wrote):
J'ai un bout de code qui recupere les exceptions a coup de
eval {....die ...};
if ($@) {
...
die ... # rethrow
}

probleme: comment debugguer tout ca ?

j'aimerais bien que perl -d me montre une stack trace a l'endroit du
premier die...



Il est encore possible d'utiliser $SIG{__DIE__} pour capter 'die'
(cf. perlvar) même si la documentation dit qu'un jour cette
possibilité n'existera plus dans les 'eval'.

Mais je ne comprends pas le besoin... Pourquoi ne pas instrumenter
l'appel à 'die' lui-même en lui passant une référence comme argument
(cf. perldoc -f die) ? Dans cette référence on peut stocker toute
l'information nécessaire...



En fait, j'ai ete un peu vite en description... ce qui m'interesse, c'est
un cas ou ce n'est pas moi qui suis a l'origine du die. En l'occurrence,
un $object->method avec $object qui vaut undef...

Et perl -d me donne un backtrace... du 2e die. Et j'aimerais non pas capter
die, mais pouvoir dire "si debugguer, alors tu me fais un backtrace dans
l'eval, PUIS tu recuperes l'exception, puis tu continues" et je ne vois
pas trop comment faire...



Sans l'avoir testé via le debugger (je ne l'utilise quasiment jamais),
je pense que le code suivant peut aider :

sub f {
die "erreur";
}
eval {
$SIG{__DIE__} = sub {
warn "die handler: @_n"; # !!!
};
f();
}
if ($@) {
warn "$@n";
}

Dans la subroutine anonyme attachée à __DIE__ on voit très bien toute
la pile d'appel dans le contexte du premier 'die' (en passant par
f()). Cette pile est certainement visible dans le debugger... mais
aussi via le module Carp si ne souhaite pas utiliser le debugger :

use Carp;
sub f {
die "erreur";
}
eval {
$SIG{__DIE__} = sub {
Carp::cluck "die handler: @n";
};
f();
};
if ($@) {
warn "$@n";
}


--
Paul Gaborit - Perl en français -
espie
Le #20438731
In article Paul Gaborit
Sans l'avoir testé via le debugger (je ne l'utilise quasiment jamais),
je pense que le code suivant peut aider :


Heureux homme... moi je n'ai pas le choix, avec du gros, gros code en
production, quand d'aventure ca plantouille, je peux difficilement demander
mieux a mon bug-reporter que de me faire un perl -d....

sub f {
die "erreur";
}
eval {
$SIG{__DIE__} = sub {
warn "die handler: @_n"; # !!!
};
f();
}
if ($@) {
warn "$@n";
}

Dans la subroutine anonyme attachée à __DIE__ on voit très bien toute
la pile d'appel dans le contexte du premier 'die' (en passant par
f()). Cette pile est certainement visible dans le debugger... mais
aussi via le module Carp si ne souhaite pas utiliser le debugger :

use Carp;
sub f {
die "erreur";
}
eval {
$SIG{__DIE__} = sub {
Carp::cluck "die handler: @n";
};
f();
};
if ($@) {
warn "$@n";
}


Bon, j'essaierai sans doute ca ce week-end et je te tiens au courant...
Paul Gaborit
Le #20438721
À (at) Wed, 28 Oct 2009 07:46:08 +0000 (UTC),
(Marc Espie) écrivait (wrote):

In article Paul Gaborit
Sans l'avoir testé via le debugger (je ne l'utilise quasiment
jamais), je pense que le code suivant peut aider :



Heureux homme... moi je n'ai pas le choix, avec du gros, gros code en
production, quand d'aventure ca plantouille, je peux difficilement demander
mieux a mon bug-reporter que de me faire un perl -d....



C'est quoi un "bug-reporter" ? C'est un utilisateur à qui tu demandes
de t'envoyer une trace lors d'un plantage ?

Dans ce genre de situations, je préfère utiliser la technique que je
donnais pour dérouter les appels à "die" et enregistrer moi-même les
informations qui m'intéressent dans un fichier de log.

[...]
Bon, j'essaierai sans doute ca ce week-end et je te tiens au
courant...



Tu m'en diras des nouvelles ! ;-)

--
Paul Gaborit - Perl en français -
espie
Le #20553371
Avec pas mal de delai, j'ai finalement resolu mon probleme differemment.

La ou j'avais:
eval {
# This is the actual very small loop that adds all packages
$state->tracker->add_sets(@todo2);
while (my $set = shift @todo2) {
unshift(@todo2, install_set($set, $state));
}
};
my $dielaster = $@;

j'ai maintenant:

my $code = sub {
# This is the actual very small loop that adds all packages
$state->tracker->add_sets(@todo2);
while (my $set = shift @todo2) {
unshift(@todo2, install_set($set, $state));
}
};

if ($state->{defines}->{debug}) {
&$code;
} else {
eval { &$code; };
}
my $dielater = $@;



comme souvent, suffit de nommer ce avec quoi on bosse, et ca ne me coute
pas plus cher de dire aux gens de relancer ma commande avec -F debug
pour avoir un backtrace raisonnable...

Je pourrais carrement rendre ca automatique a coup de test sur le
hash %DB::sub, mais je prefere laisser ca en manuel pour l'instant...
Paul Gaborit
Le #20556091
À (at) Sat, 14 Nov 2009 10:51:51 +0000 (UTC),
(Marc Espie) écrivait (wrote):

j'ai maintenant:

my $code = sub {
# This is the actual very small loop that adds all packages
$state->tracker->add_sets(@todo2);
while (my $set = shift @todo2) {
unshift(@todo2, install_set($set, $state));
}
};

if ($state->{defines}->{debug}) {
&$code;
} else {
eval { &$code; };
}
my $dielater = $@;



Pourquoi pas si cela te semble plus simple.

Juste une remarque sur l'utilisation de :

&$code;

Pourquoi ne pas faire au moins :

&$code();

ou mieux :

$code->();

C'est plus clair car on voit immédiatement que c'est un appel de
fonction et ça n'utilise pas le mécanisme caché du '&'. À moins
évidemment que ne ce soit volontaire...

--
Paul Gaborit - Perl en français -
espie
Le #20556881
In article Paul Gaborit
Juste une remarque sur l'utilisation de :

&$code;

Pourquoi ne pas faire au moins :

&$code();

ou mieux :

$code->();

C'est plus clair car on voit immédiatement que c'est un appel de
fonction et ça n'utilise pas le mécanisme caché du '&'. À moins
évidemment que ne ce soit volontaire...



C'est volontaire: c'est du refactoring bete, et precisement, j'ai envie
de rediriger vers &code() "comme si" c'etait ce qui etait la depuis le
debut. Apres, je vais faire une passe de re-nettoyage (en l'occurrence, j'ai
deux programmes qui commencent a avoir enormement de code en commun dans
cette zone, donc, ca va finir en application du Design Pattern
Template Method de facon tres nette).
Publicité
Poster une réponse
Anonyme