59 votes

NullPointerException trace de la pile non disponible sans débogage de l'agent

J'ai récemment trouvé un bug qui provoque une NullPointerException. L'exception est interceptée et connecté à l'aide d'un slf4j déclaration. Abrégé de code ci-dessous:

for(Action action : actions.getActions()) {
    try {
        context = action.execute(context);
    } catch (Exception e) {
        logger.error("...", e);
        break;
    }
}

Comme vous pouvez le voir, rien de fantaisie. Cependant, de tous les enregistrement d'exception déclarations que nous avons, tout ce ne pas imprimer une trace de la pile. Tous les imprimés, c'est le message (représentés par des "...") et le nom de la classe exception (java.lang.NullPointerException).

Depuis la trace de la pile sur une exception est pas chargé, j'ai pensé que peut-être il y a une instruction de la réorganisation de problème de la sorte, et a décidé de faire appel e.getStackTrace() avant l'instruction de journal. Cela ne faisait aucune différence.

J'ai donc décidé de redémarrer avec le débogage de l'agent activé. Cependant, parce que j'ai même attaché au processus, j'ai remarqué que maintenant les traces de la pile ont l'impression. Donc clairement la présence de débogage de l'agent causé certaines des informations de débogage supplémentaires deviennent disponibles.

Depuis, j'ai ensuite fixé à la cause de l'exception. Mais je voudrais savoir pourquoi la trace de la pile n'était pas disponible sans un débogueur. Tout le monde sait?

Précisions: ce n'est pas un enregistrement d'émission. Imaginez la même try/catch de la clause, mais dans le catch, j'ai l'impression que la valeur de:

e.getStackTrace().length

Sans un débogueur cette affiche '0', avec un débogueur, il imprime un nombre positif (9 dans ce cas).

Plus d'infos: ce qui se passe sur JDK 1.6.0_13, 64bit, amd64 linux 2.6.9

89voto

vesparun Points 576

Avec la JVM drapeau -XX:-OmitStackTraceInFastThrow vous pouvez désactiver l'optimisation des performances de la JVM pour ce cas d'utilisation. SI ce paramètre est donné, ce qui désactive le drapeau, la stacktrace seront disponibles.

Pour plus d'informations, veuillez consulter les notes suivantes:

"Le compilateur dans le serveur VM offre désormais correcte de la pile backtraces pour tous "à froid" des exceptions intégrées. Pour plus de performances, lorsqu'une exception est levée un peu de temps, la méthode peut être recompilé. Après recompilation, le compilateur peut choisir une plus tactique à l'aide de préaffectés exceptions qui ne fournissent pas de trace de la pile. Pour désactiver complètement l'utilisation de préaffectés exceptions, l'utilisation de ce nouveau drapeau: -XX:-OmitStackTraceInFastThrow." http://java.sun.com/j2se/1.5.0/relnotes.html

19voto

Nick Fortescue Points 18829

Est-il possible que ce code est dans une boucle interne? Puis ensuite compilateur JIT peut-être de la compilation de la pile d'appel pour cela à du code natif, perdre de la pile de l'information. Puis, quand vous attacher le débogueur, il désactive le JIT, rendant l'information accessible à nouveau.

L'autre manuel exceptions garder l'affichage de l'information que l'équipe n'est pas l'optimisation.

Il ressemble à ce qui est parfois le cas pour les autres à partir d'un commentaire dans ce code source de la classe à la ligne 102:

http://logging.apache.org/log4j/1.2/xref/org/apache/log4j/spi/LocationInfo.html

0voto

seth Points 18409

Je peux reproduire cela, mais il semble un peu étrange que ce serait passe dans votre Action quelque part.

Si vous appelez setStackTrace avec un tableau vide, qui va provoquer le texte à afficher.

 public class Fark {
   public static void main(String[] args) {
       try {
           Fark.throwMe(args.length != 0);

       }
       catch (Exception e) {
           e.printStackTrace();
       }

   }

     public static final void throwMe(boolean arg) throws Exception{
         Exception e = new NullPointerException();
         if (arg) {
           e.setStackTrace(new StackTraceElement[0]);
         }
         throw e;
     }
 }

En cours d'exécution....

% java Fark
java.lang.NullPointerException
        at Fark.throwMe(Fark.java:15)
        at Fark.main(Fark.java:5)

% java Fark nothing
java.lang.NullPointerException

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