Question

Je l'ai récemment trouvé un bug qui provoque une NullPointerException. L'exception est interceptée et enregistrée en utilisant une instruction standard slf4j. Code ci-dessous Abridged:

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

Comme vous pouvez le voir, rien d'extraordinaire. Cependant, toutes les déclarations de consignation d'exception que nous avons, seulement celui-ci n'imprime pas trace de la pile. Tout ce qu'il imprime est le message (représenté comme « ... ») et le nom de la classe d'exception (java.lang.NullPointerException).

Puisque la trace de la pile sur une exception est chargée paresseux, je pensais que peut-être il est une question réordonnancement d'instructions de quelque sorte et a décidé d'appeler e.getStackTrace () avant l'instruction de journal. Cela ne fait aucune différence.

Alors j'ai décidé de redémarrer avec l'agent de débogage activé. Cependant, parce que je même attaché au processus, j'ai remarqué que maintenant les traces de la pile imprimaient. Il apparaît donc clairement la présence de l'agent de débogage a causé des informations de débogage supplémentaires deviennent disponibles.

J'ai depuis lors fixé la cause de l'exception. Mais je voudrais savoir pourquoi la trace de la pile était disponible sans un débogueur. Quelqu'un sait?

Précision: ce n'est pas un problème de l'exploitation forestière . Imaginez le même try / clause catch, mais dans la prise, j'imprime la valeur de:

e.getStackTrace().length

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

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

Était-ce utile?

La solution

Est-il possible que ce code est dans une boucle intérieure? Ensuite, alors compilateur JIT peut compilera la pile d'appel pour que ce code natif, perdre l'information pile. Ensuite, lorsque vous connectez le débogueur, il désactive le JIT, ce qui rend l'information disponible à nouveau.

Les autres exceptions manuelles continuent d'afficher les informations que le JIT n'optimise.

On dirait que cela peut parfois se produire pour d'autres 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

Autres conseils

Avec le drapeau JVM -XX: -OmitStackTraceInFastThrow vous pouvez désactiver l'optimisation des performances de la machine virtuelle Java pour ce cas d'utilisation. Si ce paramètre est donné, ce qui désactive le drapeau, le stacktrace sera disponible.

Pour plus d'informations s'il vous plaît jeter un oeil sur les notes de version suivantes:

"Le compilateur dans le serveur VM fournit maintenant backtraces correct de la pile pour tous « froid » intégré des exceptions. Pour des raisons de performance, lorsqu'une telle exception est levée à quelques reprises, la méthode peut être recompilé. Après recompilation, le compilateur . peut choisir une tactique plus rapide en utilisant des exceptions préalloués qui ne fournissent pas une trace de la pile Pour désactiver complètement l'utilisation des exceptions préalloués, utilisez ce nouveau drapeau: -XX: -OmitStackTraceInFastThrow « . http://java.sun.com/j2se/1.5.0/relnotes.html

Je peux reproduire cela, mais il semble un peu bizarre que cela se passe dans votre action quelque part.

Si vous appelez setStackTrace avec un tableau vide, ça va causer que 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;
     }
 }

Son 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top