2009-12-09 2 views
17

Je travaille dans une grande application Perl et j'aimerais avoir des traces de pile chaque fois que 'die' est appelé. Je suis au courant du Carp module, mais je préférerais ne pas rechercher/remplacer chaque instance de 'mourir' avec 'avouer'. En outre, je voudrais des traces de pile complètes pour les erreurs dans les modules Perl ou l'interpréteur Perl lui-même, et évidemment je ne peux pas changer ceux pour utiliser Carp.Comment puis-je remplacer tous les 'die' par 'confess' dans une application Perl?

Alors, y a-t-il un moyen pour moi de modifier la fonction 'die' à l'exécution pour qu'elle se comporte comme 'confess'? Ou, y a-t-il un paramètre interpréteur Perl qui va lancer des traces de pile complètes de 'mourir'?

Répondre

32

Utilisez Devel::SimpleTrace ou Carp::Always et ils feront ce que vous demandez sans aucun travail de votre part. Ils ont un effet global, ce qui signifie qu'ils peuvent facilement être ajoutés pour une seule exécution sur la ligne de commande en utilisant par ex. -MDevel::SimpleTrace.

+1

Parfait! Merci! –

12

Qu'en est-il du réglage d'un gestionnaire de signal __DIE__? Quelque chose comme

$SIG{__DIE__} = sub { Carp::confess @_ }; 

en haut de votre script? Voir perlvar %SIG pour plus d'informations.

+0

Les modules que j'ai liés fonctionnent en réglant '$ SIG {__ DIE __}', donc oui, à la rigueur, vous pouvez faire la même chose vous-même. Les modules ont juste un peu de code supplémentaire pour rendre la sortie plus agréable :) – hobbs

+0

C'est la solution pour le traitement d'erreur fait maison. Vous pouvez faire tout ce dont vous avez besoin, comme sauvegarder des erreurs dans un fichier ou les poster par email. –

+0

C'est l'une de ces situations où la magie & brille. :) –

0

Le module Error convertira tous die s à Error::Simple objets qui contiennent un stacktrace complet (le constructeur parse le texte « au fichier ... .. ligne » et crée une trace de la pile). Vous pouvez utiliser un objet arbitraire (généralement sous-classé de Error::Simple) pour gérer les erreurs avec la préférence $Error::ObjectifyCallback. Ceci est particulièrement pratique si vous jetez fréquemment des exceptions d'autres types pour signaler d'autres événements, alors vous ajoutez juste un gestionnaire pour Error::Simple (ou toute autre classe que vous utilisez pour les erreurs) et le faites vider son stacktrace ou effectuez journalisation spécialisée en fonction du type d'erreur.

+1

Parfois, 'Error' casse le code de gestion des exceptions de quelqu'un d'autre et conduit à un petit cauchemar de débogage :) – hobbs

+0

Oui, malheureusement, c'est le cas. J'ai aussi dû abandonner récemment car il aime exporter 'avec ', ce qui est incompatible avec Moose. J'ai surtout conclu maintenant que les exceptions sont mauvaises. :) – Ether

2

En général, je veux seulement remplacer les die s un peu de code, donc je localise le gestionnaire __DIE__:

{ 
use Carp; 
local $SIG{__DIE__} = \&Carp::confess; 

.... 
} 

En tant qu'outil de développement, cela peut fonctionner, mais certains modules jouer des tours avec cela pour obtenir leurs caractéristiques à travailler. Ces fonctionnalités peuvent se casser de manière étrange lorsque vous remplacez le gestionnaire qu'ils attendaient. Ce n'est pas une bonne pratique, mais cela arrive parfois.

Questions connexes