2011-01-06 10 views
5

Ho un'applicazione cross-platform molto complessa. Recentemente il mio team ed io abbiamo eseguito test di stress e abbiamo riscontrato diversi arresti anomali (e core dump che li accompagnavano). Alcuni di questi dump di core sono molto precisi e mostrano la posizione esatta in cui si è verificato l'arresto anomalo con circa 10 o più frame di stack. Altri a volte hanno solo un frame stack con ?? essere l'unico simbolo!Come aumentare la probabilità che i core dump di Linux corrispondano ai simboli?

Quello che mi piacerebbe sapere è:

  1. C'è un modo per aumentare la probabilità di core dump che punta nella direzione giusta?
  2. Perché il numero di frame di stack non è coerente?
  3. Qualsiasi best practice consiglia di gestire i core dump.

Ecco come compilo i binari (in modalità di rilascio):

  1. compilatore e la piattaforma: g ++ con glibc-2.3.2-95.50 su CentOS 3.6 x86_64 - Questo mi aiuta a mantenere la compatibilità con i vecchi versioni di Linux.
  2. Tutti i file sono compilati con il flag -g.
  3. I simboli di debug vengono eliminati dal file binario finale e salvati in un file separato.
  4. Quando ho un core dump, utilizzo GDB con l'eseguibile che ha creato il core e il file dei simboli. GDB non si lamenta mai che c'è una discrepanza tra il core/binario/simboli.

Eppure a volte ricevo core dump senza simboli! È comprensibile che io stia collegando la versione non di debug di libstdC++ e libgcc, ma sarebbe bello se almeno la traccia dello stack mi indicasse dove nel mio codice ha avuto origine la chiamata di istruzioni errata (anche se alla fine potrebbe finire in ??) .

risposta

7

Altre volte hanno solo un frame di stack con "??" essere l'unico simbolo!

Ci possono essere molte ragioni per questo, tra gli altri:

  • telaio stack è stato cestinato (sovrascritto)
  • EBP/RBP (x86/x64) non è attualmente in possesso di alcun valore significativo - questo può accadere ad es in unità compilati con o ASM unità che lo fanno

nota che il secondo punto può avvenire semplicemente, per esempio, glibc essendo compilato in modo. Avere le informazioni di debug per tali librerie di sistema installate potrebbe mitigare questo (qualcosa di simile a ciò che i pacchetti di glibc-debug {info, source} si trovano su openSUSE).

gdb ha più controllo sul programma rispetto a glibc, quindi la chiamata backtrace di glibc non sarebbe naturalmente in grado di stampare un backtrace se gdb non può farlo neanche.

ma la spedizione la fonte sarebbe molto più facile :-)

+2

Ciò è altamente probabile che sia il problema - se lo stack frame è stato distrutto dal bug, allora non c'è più. – caf

+0

Voto verso l'alto. Se il bug sta cestinando lo stack, allora non c'è alcun sostituto per fallire presto e ad alta voce. assert() è tuo amico. – user47559

2
  1. Hai provato a installare i simboli di debug delle varie librerie che stai utilizzando? Per esempio, la mia distribuzione (Ubuntu) fornisce libc6-dbg, libstdc++6-4.5-dbg, libgcc1-dbg ecc
  2. Se si sta costruendo con l'ottimizzazione abilitata (ad es. -O2), quindi il compilatore può offuscare il confine tra stack frame, ad esempio inline. Non sono sicuro che ciò causerebbe backtrace con un solo stack frame, ma in generale la regola è di aspettarsi una grande difficoltà di debug poiché il codice che si sta guardando nel core dump è stato modificato e quindi non corrisponde necessariamente alla tua origine .
3

In alternativa, su un sistema glibc, è possibile utilizzare la chiamata backtrace funzione (o backtrace_symbols o backtrace_symbols_fd) e filtrare i risultati da soli, in modo vengono visualizzati solo i simboli appartenenti al proprio codice. È un po 'più di lavoro, ma poi, puoi davvero adattarlo alle tue esigenze.