Domanda

Ho un bug da qualche parte che sta causando la mia app a svanire solo senza un messaggio di errore o qualcosa di simile. L'applicazione appena dissapears dallo schermo e non è più quotata al Task Manager.

L'applicazione è un'applicazione C ++ Builder (CBuilder2007), e ho provato tutto ciò che ho in mente per cercare di catturare questo errore. Capita molto di rado, non è mai caduto sulla mia macchina e solo una volta nelle macchine di prova che abbiamo in ufficio. Con uno dei nostri clienti succede un po 'più frequenti, ma non abbiamo trovare un modo per farlo accadere, o per trovare le circostanze in cui accade. Si tratta di un'applicazione multithread pesante.

Ho MadExcept abilitata in questa applicazione, ma non prendo nulla. Ho già aggiunto i gestori che utilizzano le routine set_terminate e set_unexpected RTL, senza alcuna fortuna.

L'unica informazioni che ho è da un involucro "loader app" L'ho fatto, per ottenere il codice di ritorno da l'applicazione principale. Esce con il codice C0000005, che a mio avviso significa una violazione di accesso è accaduto. La cosa strana è che, come detto, non c'è nemmeno la casella di errore di Windows o qualcosa del genere.

La domanda sarebbe: tutte le idee per cercare di prendere questo? Come io non ho nemmeno idea di dove questo potrebbe accadere (ho un sacco di registrare tutto l'app, ma il "percorso" prima l'applicazione si blocca, non ha portato a nessuna parte) la mia idea con le routine set_terminate e set_unexpected era per ottenere una traccia dello stack per cercare di vedere dove l'errore è stato generato, ma finora tali routine non vengono chiamati a tutti (almeno l'unica volta che questo è successo qui nel mio ufficio)

Grazie in anticipo


[Aggiornamento 22.Sept.2009] Utilizzando AddVectoredHandlerException sono stato in grado di ottenere un callstack dal crollo, e ora posso iniziare a cercare di isolare e correggere il bug. Grazie !!!

È stato utile?

Soluzione

terminate / unexpected viene chiamato solo dal runtime C ++, e solo per eccezioni C ++.

Violazione di accesso è un'eccezione SEH - per la cattura di che, è necessario SetUnhandledExceptionFilter , o AddVectoredExceptionHandler (se si tratta di> = XP). È quindi possibile creare un minidump, utilizzando MiniDumpWriteDump e relativo.

Altri suggerimenti

ho incontrato problemi come questo un paio di volte, in cui l'applicazione sembra fermarsi semplicemente. Non ci sono gestori di eccezioni o gestori di crash o tali vengono invocati. L'applicazione sembra semplicemente di interrompere immediatamente.

Purtroppo, non posso offrire alcuna facile consiglio su come capirlo. Le altre risposte qui hanno alcune buone idee. Se non si dispone già di avere qualcosa per catturare le eccezioni non gestite secondo reponse di PiotrLegnica, allora si dovrebbe fare così.

Tuttavia, se il programma è veramente terminato immediatamente come le volte che ho visto questo, allora anche un gestore registrato con SetUnhandledExceptionFilter non aiuterà. Il programma è fermare tutta l'esecuzione e l'abbandono della memoria prima del gestore viene mai richiamato.

Alcune idee in modo da venire in mente se:

  • Controlla il tuo codice di base per qualsiasi utilizzo di TerminateProcess o TerminateThread . Potrei sbagliarmi, ma credo che l'utilizzo di questi potrebbe essere in grado di causare i sintomi che stai vedendo.
  • Controlla qualsiasi utilizzo di puntatori a funzione, tra cui callback e WindowProcs passati alle API di Windows. Assicurarsi che le convenzioni di chiamata, elenchi di parametri e valori di ritorno tutti i match in modo corretto. Se un puntatore a funzione viene colato per rendere il codice di compilazione, si può nascondere una mancata corrispondenza che potrebbero causare brutte cose accadano.
  • Considerare eventuali librerie 3rd-party o componenti ActiveX (o tali) che si sta utilizzando. Forse hanno un bug nel proprio codice che causa questo problema in situazioni oscure. Si potrebbe provare a posizionare le dichiarazioni di registrazione prima e dopo le chiamate alle loro funzioni per vedere se questo può definire in cui il programma si ferma.
  • E se non altro aiuta, mettere più di registrazione in tutto il proprio codice.

E in tema di registrazione: Quando ho dovuto aiutare a rintracciare un problema come questo, dove al mio lavoro, abbiamo finito per fare un meccanismo di registrazione che creerebbe un registro con nome univoco ogni volta che il programma è iniziato e sarebbe cancellarlo se il programma si è conclusa normalmente. In questo modo, un altro file di registro sarebbe rimasto in vigore ogni volta che si è verificato il problema di terminazione. Abbiamo usato un timbro di data e ora come parte del aspetto unico di denominazione. Il contenuto dei log era semplicemente una registrazione di quali azioni sono state accadendo nel programma. Siamo passati attraverso diverse iterazioni di esaminare i registri e quindi l'aggiunta di ulteriori dichiarazioni di registrazione fino a quando questo finalmente ci ha portato a sorgente. E mentre rintracciare il problema, questo meccanismo ci ha dato un'idea molto chiara su quanto spesso il problema stava accadendo. Si potrebbe prendere in considerazione qualcosa di simile.

Ho visto che questo accada a codice C ++ due volte prima:

  1. Quando si carica dinamicamente un'API di Windows utilizzando LoadLibrary e GetProcAddress e quindi chiamando attraverso un puntatore a funzione dichiarata con la convenzione di chiamata sbagliata (che avrebbe dovuto avere __stdcall ma non l'ha fatto).

  2. Quando una classe ha un puntatore alla funzione come variabile membro, e il puntatore funzione è chiamata prima di essere inizializzato.

Devi eseguire l'applicazione in modalità di debug, e fare un test di stress eseguendo serie di scenari complicata sempre di più, in modo da poter intercettare l'eccezione nella modalità di debug.

Prova anche a rivedere il codice di nuovo che contiene l'accesso alla memoria condivisa tra le discussioni, può essere il problema da mulithreading, si può provare a mettere le serrature su ogni accesso alla memoria condivisa per ottenere certi mulithreading è la ragione (ma questo sarà diminuire le prestazioni )

Re: la scomparsa app, non le macchine dei clienti sono i "Segnala errori" Impostazione disattivato in Windows? E 'sepolto nel pannello di controllo "Sistema", e quando è spento viene soppressa la finestra di notifica di arresto normale di Windows.

Forse l'aggiunta di un buon, vecchio stile gestore di segnale potrebbe almeno dare qualche indicazione di quello che è successo?

Hai una situazione difficile se non si può riprodurre a livello locale. Catturare un crash dump, o la cattura il programma in atto con un debugger è sicuramente la scelta migliore, come altri hanno suggerito.

Se questo fosse il mio problema, mi piacerebbe provare il monitoraggio con Process Monitor da Sysinternals. Impostare fino a guardare solo il processo, e assicurarsi che sia supportata da un file, se ci vorrà molto tempo. Questo potrebbe dirvi quale thread è attivo e ciò che sta accadendo, quando termina il processo. Si potrebbe anche cercare di trovare l'equivalente di 'capriata' per Windows -. Un programma per monitorare le chiamate di sistema

Ci sono due cose che ho visto fare in passato che si potrebbe prendere in considerazione: overflow dello stack (ricorsione infinita, i parametri di cattivi che causano grandi variabili temporanee per essere collocata sullo stack, ecc), o un'eccezione non gestita in un secondario thread.

Configura il tuo app per scrivere un minidump in caso di crash.

Io non sono sicuro di come questo sia in CBuilder, ma in Visual Studio è possibile caricare questa discariche direttamente e vi mostra una stack completo e la linea di codice sorgente che ha causato l'incidente.

Ho usato questo molto per trovare la causa di incidenti che si sono verificati sulle macchine dei clienti.
Tuttavia soprattutto per le applicazioni multi-threaded, è probabile che il vero errore (memoria ad esempio è stato rilasciato ai primi) successo un po 'prima del crollo vero e proprio, quindi potrebbe essere ancora molto difficile trovare la causa principale.

Sottoscrivi Segnalazione errori Windows. Le probabilità sono che alcuni dei vostri clienti riporterà l'AV a Microsoft, che ha intenzione di condividere felicemente le tracce dello stack raccolti con voi. Come un vantaggio, si ottengono figure dure sull'affidabilità della vostra applicazione. Gestione ama quelli. Per esempio. è possibile impostare un obiettivo di "ridurre la frequenza degli errori del 50% entro il 2010".

Metti la tua applicazione in esecuzione, quindi collegare il windbg (crash-mode), che la prima occorrenza di eccezione della seconda opportunità è generato discarica. Ricordatevi di mettere i file di simboli (PDB).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top