So che posso ottenere la traccia stack del thread corrente utilizzando backtrace() o [NSThread callStackSymbols], ma come ottengo la traccia di stack di un thread DIVERSO (ammesso che sia stato congelato)?Stampa di una traccia di stack da un'altra discussione
risposta
MODIFICA: la mia risposta originale non verrà stampata da un thread arbitrario. Da allora ho scritto un corretta attuazione nel mio progetto gestione dei crash: https://github.com/kstenerud/KSCrash
In particolare, questi file:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.c
con qualche aiuto da:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.c
Quello che fate è:
- fare una nuova struttura di contesto della macchina (_STRUCT_MCONTEXT)
- Fill nel suo stato dello stack mediante thread_get_state()
- Prendi il contatore di programma (first stack trace entry) e frame pointer (tutto il resto)
- Passare attraverso il frame stack puntato dal puntatore del frame e memorizzare tutte le istruzioni a indirizzi in un buffer per un uso successivo.
Si noti che è necessario mettere in pausa la discussione prima di eseguire questa operazione oppure è possibile ottenere risultati imprevedibili.
lo stack frame è pieno di strutture che contiene due puntatori:
- Puntatore al livello successivo sulla pila
- indirizzo di istruzioni
quindi è necessario tenerne conto quando percorrendo il fotogramma per compilare la traccia dello stack. C'è anche la possibilità di uno stack corrotto, che porta a un puntatore cattivo, che farà crashare il tuo programma. È possibile aggirare questo copiando la memoria usando vm_read_overwrite(), che prima chiede al kernel se ha accesso alla memoria, quindi non si blocca.
Una volta ottenuta la traccia dello stack, è sufficiente richiamare backtrace() su di esso come normale (il gestore di crash deve essere async-safe in modo da implementare il proprio metodo backtrace, ma in casi normali backtrace() va bene) .
Ecco un modo più sicuro per ottenere il callstack da un altro thread: Implementation e some background information. Usa la gestione del segnale e genera un gestore di segnale nel thread di destinazione. Ha anche il vantaggio che è più multipiattaforma della tua soluzione, cioè dovrebbe funzionare ovunque tu abbia <signal.h>
e <execinfo.h>
.
Per la stampa, è possibile utilizzare backtrace_symbols
come si fa nel proprio suggerimento. Ma potresti essere interessato a una versione estesa di questo come implementato here.Utilizza libbfd (da binutils; la versione recente funziona anche principalmente su MacOSX, vedi here per una piccola limitazione che potrebbe non essere rilevante per te) per leggere le informazioni di debug e per aggiungere numero di riga e altre informazioni (ricade anche su dladdr
se tutto il resto fallisce, questo è ciò che sta facendo backtrace_symbols
).
- 1. Stampa traccia dello stack da un gestore di segnale
- 2. Stampa traccia di stack nella finestra di output
- 3. traccia dello stack python di stampa senza sollevare nessuna eccezione
- 4. Nessuna traccia di stack da NSAssert
- 5. Log.e non stampa la traccia dello stack di UnknownHostException
- 6. Scrivi traccia di stack quando un'eccezione viene generata da un'altra discussione
- 7. Errore di traccia stack
- 8. Come posso estrarre variabili locali da una traccia di stack?
- 9. Individuazione della traccia dello stack effettivo Java da una traccia stack javascript
- 10. Stampa i valori dei parametri sulla traccia dello stack
- 11. Django: manage.py non stampa la traccia stack per errori
- 12. Stampa una traccia dello stack su stdout sugli errori in Django durante l'utilizzo di manage.py runserver
- 13. Ottenere una traccia stack da SBT con Scala
- 14. Stampa stack di chiamate completo su printStackTrace()?
- 15. Generatori ES6: traccia di stack scadente da iterator.throw (err)
- 16. Come ridurre l'output in una traccia stack?
- 17. Traccia stack come stringa
- 18. Ottenere una traccia stack di uno script PHP sospeso
- 19. Xcode - Traccia stack di chiamata su assert?
- 20. Console di traccia stack in IntelliJ IDEA
- 21. Perché non ottengo nessun numero di linea da una traccia stack creata da Eccezioni?
- 22. Come posso ottenere una traccia di stack JavaScript in Firefox?
- 23. Come ottenere una traccia di stack in .NET nell'esecuzione normale?
- 24. Traccia stack Java su Windows
- 25. Traccia stack "trapping" middleware rack
- 26. Subprocesso Python.Popen da una discussione
- 27. Ottenere una discussione da Id
- 28. Perché la mia eccezione Java non stampa una traccia di stack quando viene lanciata all'interno di SwingWorker?
- 29. Come stampare la traccia di stack di StackOverflowException
- 30. Stampa PHP Call Stack
Si noti che è necessario sospendere il thread mentre si sta leggendo il suo stack. – Albert
Inoltre, sei sicuro che funzioni? Usa '__builtin_frame_address', che riguarda sempre il ** thread ** corrente. – Albert
Quindi risulta che non funziona (stampa una traccia dello stack, ma non mi sono reso conto che stava stampando dal thread corrente). Ho del nuovo codice che funziona come previsto, ma non è ancora pronto per il rilascio. Pubblicherò un aggiornamento una volta pronto. – Karl