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:

  • non vedo un'opzione di collegamento rdynamic per il g ++ versione (4.0.1) sto usando.
  • -g/-g3 non fa alcuna differenza.
  • abi::__cxa__demangle non sembra di fare nulla

        
  • È stato utile?

    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.

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