Domanda

Di recente ho trovato un bug che causa un NullPointerException. L'eccezione viene catturato e registrato utilizzando un'istruzione slf4j standard. Codice abbreviato qui di seguito:

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

Come si può vedere, niente di speciale. Tuttavia, di tutte le dichiarazioni di registrazione di eccezione che abbiamo, solo questo non stampa una traccia dello stack. Tutto viene stampato è il messaggio (rappresentato come "...") e il nome della classe di eccezione (java.lang.NullPointerException).

Dal momento che l'analisi dello stack su un eccezione è caricato in modo pigro, ho pensato che forse c'è un problema di riordino istruzioni di qualche tipo e ha deciso di chiamare e.getStackTrace () prima dell'istruzione di registro. Questo ha fatto alcuna differenza.

Così ho deciso di ripartire con l'agente di debug abilitato. Tuttavia, poiché ho anche attaccato al processo, ho notato che ora le tracce dello stack sono stati stampati. Così chiaramente la presenza di un agente di debug causato alcune informazioni di debug aggiuntive per diventare disponibili.

Da allora ho fissato la causa principale eccezione. Ma mi piacerebbe sapere perché la traccia dello stack non era disponibile senza un debugger. Qualcuno sa?

Chiarimento: questo non è un problema di registrazione . Immaginate la stessa clausola try / catch, ma nella cattura, ho stampare il valore di:

e.getStackTrace().length

Senza un debugger questa stampe '0', con un debugger si stampa un numero positivo (9 in questo caso).

Più informazioni: questo sta accadendo su JDK 1.6.0_13, 64bit, AMD64, Linux 2.6.9

È stato utile?

Soluzione

E 'possibile che questo codice è in un ciclo interno? Allora poi compilatore JIT potrebbe essere compilando lo stack di chiamate per questo in codice nativo, perdere le informazioni di stack. Poi, quando si collega il debugger viene disattivato il JIT, rendendo le informazioni disponibili di nuovo.

Le altre eccezioni manuali mantenere la visualizzazione delle informazioni come il JIT non sta ottimizzando.

Sembra che questo a volte può accadere per gli altri da un commento in questo codice sorgente della classe alla riga 102:

http: //logging.apache. org / log4j / 1.2 / riferimento esterno / org / apache / log4j / SPI / LocationInfo.html

Altri suggerimenti

Con la JVM bandiera XX: -OmitStackTraceInFastThrow è possibile disattivare l'ottimizzazione delle prestazioni della JVM per questo caso d'uso. Se viene dato questo parametro, che disabilita la bandiera, lo stacktrace sarà disponibile.

Per ulteriori informazioni si prega di dare un'occhiata alle seguenti note di rilascio:

"Il compilatore nel server VM fornisce ora backtrace dello stack corrette per tutti 'a freddo' eccezioni built-in. Per il calcolo delle prestazioni, quando un tale viene generata un'eccezione un paio di volte, il metodo può essere ricompilato. Dopo la ricompilazione, il compilatore . può scegliere una tattica più veloce utilizzando eccezioni preassegnati che non forniscono una traccia dello stack Per disabilitare completamente l'uso di eccezioni preassegnati, utilizzare questa nuova bandiera: -XX: -OmitStackTraceInFastThrow ". http://java.sun.com/j2se/1.5.0/relnotes.html

Posso replicare questo, ma sembra un po 'strano che questo sarebbe successo nella vostra azione da qualche parte.

Se si chiama setStackTrace con un array vuoto, che sarà causa solo il testo da visualizzare.

 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;
     }
 }

L'esecuzione ....

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

% java Fark nothing
java.lang.NullPointerException
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top