2009-06-24 13 views
5

Sto tentando di eseguire il debug di un problema nella mia applicazione Java che non genera errori, senza eccezioni e nemmeno arresta l'app in modo anomalo (sembra che l'errore si verifichi in un thread separato).Come si esegue il debug degli errori invisibili nelle applicazioni Java?

Il problema sembra essere all'interno di una chiamata a una funzione di libreria (è JAXBContext.newInstance(String) se ciò è importante). Il programma raggiungerà la linea appena prima della chiamata, ma non quella subito dopo. I miei blocchi catch non sono stati inseriti e il programma continua a funzionare.

Il problema si verifica durante il tentativo di eseguire il rendering di una risposta XML a una richiesta Web inviata tramite Struts. La richiesta è stata gestita e il codice deve eseguire il marshalling dell'oggetto risposta. Il client riceve subito una risposta (quindi il codice non sembra bloccarsi in un ciclo), ma è solo vuoto.

Ho impostato un punto di interruzione poco prima della riga problematica ma il debugger ci passa sopra, non ho idea del perché.

Sto usando eclipse e l'applicazione viene eseguita all'interno di un contenitore OSGi (Apache Felix) che è stato avviato con -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. Da dentro Eclipse I quindi utilizzare le impostazioni di debug per "Remote Java application" per connettere il debugger.

Quali sono le tecniche per ottenere un simile problema?

+2

Sei sicuro che l'IDE punta allo stesso codice sorgente che formava i binari sul server? –

+0

Sì, è tutto nella mia macchina locale e il contenitore OSGi sta eseguendo il codice direttamente dalla directory di output del mio IDE. –

+0

Non conosco il contenitore OSGi, come JBoss sposta i file binari distribuiti in un'altra directory? Proverei a modificare il codice, un System.out.println o qualcosa di simile, quindi assicurati che venga eseguito per confermare questo. Normalmente ho trovato che le linee di codice saltate del debugger indicano che l'IDE e il server non sono sincronizzati l'uno con l'altro. –

risposta

0

forse all'interno della chiamata si verifica un ciclo di infititi ed è per questo che non si ottiene ulteriore - ma questo potrebbe non causare un arresto anomalo (a meno che la memoria non venga utilizzata in ogni ciclo).

+1

No, non la penso così. L'errore si verifica quando si gestisce una richiesta web in arrivo tramite Struts e il client ottiene un risultato (che è vuoto) subito. Quindi l'app non si blocca, salta fuori dall'elaborazione. –

1

Se sei sicuro che il problema sia da qualche parte all'interno di tale metodo, potresti provare a guardare lo JAXB source code.

EDIT:

Beh, se si arriva davvero male si può costruire la propria copia privata con il debug di strumentazione. Spero che non dovrai ricorrere a quello.

+0

Beh, ci provo, ma senza far entrare il debugger, potrei avere delle difficoltà. –

2

Si potrebbe provare a ottenere un Thread Dump - che vi dirà se alcuni metodi stanno bloccando (ad esempio in attesa di input). [Modifica: rileggendo la tua domanda originale, ottenere un dump del thread probabilmente non ti aiuterà dato che sembra che nulla stia effettivamente bloccando. Ma lo lascio qui come lo trovo utile in molte altre situazioni!]

Se pensi che l'errore stia accadendo in un'altra discussione puoi anche impostare un UncaughtExceptionHandler per provarlo e catturarlo.

+0

Blocco: no, non questa volta. UncaughtExceptionHandler è stata una buona idea, sfortunatamente non ha catturato nulla. –

6

Probabilmente una domanda ovvia, ma sei sicuro che stai prendendo Throwable? Un'eccezione non controllata potrebbe facilmente causare la morte del thread in questione (supponendo che nessuno sopra di te nello stack di chiamate lo stia prendendo).

Poiché si sta sospendendo la VM all'avvio con gli argomenti di debug, presumo che tu abbia confermato che il debugger sta collegando correttamente. Il fatto che tu dica che il debugger salta oltre la chiamata è molto sospetto. Sei in grado di colpire qualsiasi punto di interruzione in questa applicazione? Che ne pensi di questa classe? Che dire in questa discussione?

Come si restringe la linea in questione senza il debugger? println/debug su un file?

È possibile incollare uno snippet di codice del metodo in questione?

È possibile confermare la teoria che il thread sta morendo creando un secondo thread prima che si verifichi il problema e unendolo al thread che si ritiene stia morendo.Quindi il metodo run() del secondo thread verrebbe invocato quando il thread in questione termina e sapresti che è morto (ma non sapremmo ancora perché).

In risposta alla tua domanda generale, quando ho un bug in un'app Java che non riesco a riprodurre nel debugger (cosa che accade di volta in volta per vari motivi), modifico in modo incrementale il mio codice con sysout printlns o output in file. Se necessario, posso anche modificare il codice che il mio codice sta invocando. Se non si dispone del codice sorgente del codice che si sta invocando, è possibile provare uno dei numerosi framework BCI per iniettare il codice byte nei metodi in questione. È un processo noioso, ma succede solo occasionalmente.

+0

+1 Non tutti i Throwables sono Eccezioni e di solito rileviamo Eccezioni; è facile per questo scivolare oltre noi. –

Problemi correlati