Generazione backtrace C ++ in OS / X (10.5.7)
-
16-09-2019 - |
Domanda
Sono stato utilizzando backtrace e backtrace_symbols per generare tracce dello stack programmatiche ai fini della registrazione / diagnosi. Sembra funzionare o meno, però, sto diventando un po 'di pressare e non ci sono numeri di file / linea di accompagnamento associati a ciascuna funzione invocazione (come mi aspetto all'interno di una chiamata gdb bt o qualcosa del genere). Ecco un esempio:
1 leonardo 0x00006989 _ZN9ExceptionC2E13ExceptionType + 111
2 Leonardo 0x00006a20 _ZN9ExceptionC1E13ExceptionType + 24
3 leonardo 0x0000ab64 _ZN5Rules11ApplyActionER16ApplicableActionR9GameState + 1060
4 leonardo 0x0000ed15 _ZN9Simulator8SimulateEv + 2179
5 leonardo 0x0000eec9 _ZN9Simulator8SimulateEi + 37
6 leonardo 0x00009729 principale + 45
7 leonardo 0x000025c6 inizio + 54
Tutto ciò che mi manca qualcosa, fare qualcosa di stupido, o è tutto quello che posso aspettare fuori backtrace su OS / X?
Alcuni altri bocconcini:
rdynamic
per il g ++ versione (4.0.1) sto usando. -g/-g3
non fa alcuna differenza.
abi::__cxa__demangle
non sembra di fare nulla
Soluzione
I backtrace in genere tornano dal backtrace_symbols nel seguente formato:
./ MyApp (_ZN4test3fooEv + 0x8) [0x821c874]
abi :: __ cxa_demangle si aspetta solo il nome della funzione. Così, alcuni analisi deve prima essere fatto sulla traccia:
std::string trace(backtrace[idx]);
// attempt to demangle
{
std::string::size_type begin, end;
// find the beginning and the end of the useful part of the trace
begin = trace.find_first_of('(') + 1;
end = trace.find_last_of('+');
// if they were found, we'll go ahead and demangle
if (begin != std::string::npos && end != std::string::npos) {
trace = trace.substr(begin, end - begin);
size_t maxName = 1024;
int demangleStatus;
char* demangledName = (char*) malloc(maxName);
if ((demangledName = abi::__cxa_demangle(trace.c_str(), demangledName, &maxName,
&demangleStatus)) && demangleStatus == 0) {
trace = demangledName; // the demangled name is now in our trace string
}
free(demangledName);
}
}
Ho provato questo è il mio progetto, e dà un po 'più bello backtrace con il seguente formato:
Test :: foo ()
Certo, non ci sono i numeri di riga, ma non sono certo che è ancora possibile.
Altri suggerimenti
Non so di qualsiasi implementazione di backtrace_symbols()
che dà più di quanto simbolo + offset.
Per quanto riguarda abi:: __cxa__demangle
, è necessario assicurarsi che si passa solo il nome del simbolo, senza il suffisso + line
, altrimenti non riconoscerà il simbolo come valido.