2013-07-16 22 views
11

Un'applicazione Android che sto attualmente sviluppando si è bloccata (risolta), a causa di ciò che avrebbe dovuto generare una IndexOutOfBoundsException. Stavo accedendo a una stringa nel metodo doInBackground di una classe che estende AyncTask, dal parametro arguments variable (cioè String ...). Accedevo accidentalmente all'indice 1 (non 0) di una stringa di argomento variabile di un elemento (leggermente imbarazzante ...). Quando l'applicazione si è arrestata per la prima volta, ho guardato il mio logcat (e molte volte di nuovo per confermare che non ero pazzo) e non c'era traccia dello stack per trovare una RuntimeException. Il mio telefono si blocca abbastanza spesso e c'è sempre una bella piccola pila di tracce da guardare e fissare, ma sono rimasto perplesso. Ecco la sezione pertinente del mio logcat (che non contiene analisi dello stack per un RuntimeException), a seguito di una dichiarazione di debug a destra prima della riga di codice che ha causato l'incidente:Perché Android logcat non mostra la traccia dello stack per un'eccezione di runtime?

W/dalvikvm(25643): threadid=11: thread exiting with uncaught exception (group=0x40c281f8) 
D/dalvikvm(25643): GC_CONCURRENT freed 1249K, 25% free 12433K/16455K, paused 2ms+6ms 
W/dalvikvm(25643): threadid=15: thread exiting with uncaught exception (group=0x40c281f8) 
I/Process (25643): Sending signal. PID: 25643 SIG: 9 
I/ActivityManager(5905): Process com.trade.nav.ges (pid 25643) has died. 
W/ActivityManager(5905): Force removing r: app died, no saved state 
I/WindowManager(5905): WIN DEATH: win 
I/WindowManager(5905): WIN DEATH: win 
I/SurfaceFlinger(1746): id=3848 Removed idx=2 Map Size=4 
I/SurfaceFlinger(1746): id=3848 Removed idx=-2 Map Size=4 
I/WindowManager(5905): WIN DEATH: win 
I/power (5905): *** acquire_dvfs_lock : lockType : 1 freq : 1000000 
D/PowerManagerService(5905): acquireDVFSLockLocked : type : DVFS_MIN_LIMIT frequency : 1000000 uid : 1000 pid : 5905 tag : ActivityManager 
W/ActivityManager(5905): mDVFSLock.acquire() 

E dopo che, un'altra attività inizia. Per riferimento, ecco il codice che ha causato l'incidente:

private class LoadImage extends AsyncTask<String, Integer, Bitmap> { 
    String url = ""; 
    //... 
    public LoadImage(ImageView iv, Context c) { 
     //... 
    } 

    protected Bitmap doInBackground(String... urls) { 
     // urls has one element 
     url = urls[1]; 
     //... 
    } 
    //... 
} 

Qualsiasi indicazioni su ciò che sta accadendo mi avrebbe fatto piacere molto, come io sono curioso di avere mai visto nulla di simile su internet. Grazie.

Edit: Non ho alcun filtro impostato

+0

Hai provato inserendo il codice di eccezione in Try Catch Block? –

+0

Sei sicuro di non aver selezionato nessun filtro? – Varun

+1

... il problema non è che ho bisogno di impedire al codice di sollevare l'eccezione di runtime, l'ho già fatto in un'altra versione del codice (ho cambiato il numero 1 in uno 0). Il problema è che la vecchia versione del codice non ha mai causato una traccia dello stack delle eccezioni di runtime da mostrare nel mio logcat. Voglio sapere perché sarebbe successo. –

risposta

10

le discussioni che sono chiaramente infrangono (notare le thread exiting with uncaught exception su due diversi thread nello stesso processo). Il processo si sta ripulendo da solo: Sending signal indica che il processo sta inviando un segnale fatale a se stesso. Quindi la domanda è perché non vedi un cumulo di discariche tra questi due.

Il dump dello stack proviene da RuntimeInit$UncaughtHandler, che è il gestore di eccezioni non rilevate globale fornito dalla struttura. L'auto-annientamento del processo avviene nel blocco finally. È difficile vedere un modo per uscire da questo senza registrare "FATAL EXCEPTION", a meno che qualcosa in Slog.e non riesca e venga generato.

Suppongo che qualcosa non funzioni in Slog.e o che qualcuno abbia sostituito il gestore di eccezioni non rilevate del framework. Quest'ultimo potrebbe accadere se nella tua app hai incorporato qualche libreria esterna, come un catcher del registro di crash o una rete pubblicitaria, e il nuovo gestore non registra l'eccezione ma uccide il processo.

È possibile rintracciarlo allegando un debugger in linguaggio Java (ad esempio Eclipse). Per impostazione predefinita, si fermerà alle eccezioni non rilevate. Da lì è possibile rintracciare, impostare punti di interruzione e passaggio singolo attraverso il gestore di eccezioni non rilevate (se si dispone di origini complete) e così via.

+0

Grazie mille. Ho intenzione di esaminarlo di più a casa, dato che non riesco a trovare il tempo per lavorare. Non ho alcuna libreria di terze parti che dovrebbe influire su questo (anche se controllerò se Aviary, un editor di immagini che uso come libreria, fa qualcosa del genere), e sto ancora vedendo altri dump dello stack nel mio logcat (come dovrebbe essere), quindi continuo ad essere incuriosito. Grazie mille per i suggerimenti tempestivi e ben informati. Buona giornata. –

6

Come sospettato da Fadden che la libreria esterna possa ignorare il gestore di eccezioni non rilevate, ho iniziato a esaminare eventuali librerie possibili. Si è scoperto che le strozzature GoogleAnalytics si arrestano in modo anomalo e impedisce la visualizzazione della traccia dello stack in logcat se si attiva enableExceptionReporting. Togliere questa riga di codice, quindi tutto torna in pista !! Quella potrebbe essere la prima volta che sono stato così felice di vedere incidenti !!