2016-07-09 10 views
12

di Linux è notoriamente utilizzato da Brendan Gregg per generare flamegraphs per C/C++, il codice JVM, nodejs codice, eccIn che modo l'utilità perf di linux capisce le tracce dello stack? utility perf

il kernel di Linux in modo nativo capire impilare tracce? Dove posso leggere di più su come uno strumento è in grado di introspettersi in tracce di stack dei processi, anche se i processi sono scritti in lingue completamente diverse?

+0

beh, non è la lingua del processo in cui viene scritta la fonte, ma del file binario che viene eseguito. In definitiva il codice della lingua viene convertito in binario (file eseguibili), che viene eseguito sul processore. Probabilmente gli eseguibili di linux sono in formato [ELF] (https://en.wikipedia.org/wiki/Executable_and_Linkable_Format). La traccia dello stack viene generata per questo codice binario. Se il file binario contiene tabelle di simboli che descrivono le sue procedure, nella traccia verranno visualizzati alcuni nomi normali. (Brendan Gregg ha descritto il problema con i simboli mancanti per Java, corrispondenti parti vuote sul grafico della fiamma.) – xealits

+0

@xealits hai il link alla nota di Brendan sui simboli mancanti di java? Questo probabilmente riempirà i pezzi mancanti per me. – Shahbaz

+0

xealiti, ELF non ha traccia di stack; e a volte può non essere facile per il kernel di Linux trovare lo stack di chiamate completo - alcuni puntatori di frame possono essere omessi dalle ottimizzazioni del compilatore. Alcune macchine virtuali Java hanno una magia nel formato stack frame: http://www.brendangregg.com/perf.html "4.4 Tracce dello stack: si compila sempre con i puntatori del fotogramma omettendo i puntatori ai frame è una cattiva ottimizzazione del compilatore che interrompe i debugger, .. il kernel 3.9, perf_events ha supportato una soluzione alternativa per i puntatori ai frame mancanti negli stack a livello utente: libunwind, che usa nano. ... Java potrebbe non mostrare gli stack completi .. a causa dell'hotspot su x86 " – osgx

risposta

24

C'è introduzione breve di tracce di stack in perf da Gregg: http://www.brendangregg.com/perf.html

4,4 Pila Tracce

compilare sempre con i puntatori del telaio. L'omissione dei puntatori ai frame è una cattiva ottimizzazione del compilatore che interrompe i debugger e, purtroppo, è spesso l'impostazione predefinita. Senza di essi, potresti vedere pile incomplete da perf_events ... Ci sono due modi per risolvere questo problema: usando i dati di nani per svuotare lo stack o restituire i puntatori di fotogramma.

Dwarf

Poiché sul kernel 3.9, perf_events ha sostenuto una soluzione mancanti puntatori ai frame in pile a livello di utente: libunwind, che utilizza nano. Questo può essere abilitato usando "-g nana". ... ottimizzazioni del compilatore (-O2), che in questo caso ha omesso il puntatore del frame. ... .. con la ricompilazione -fno-omit-frame-pointer:

lingue non in stile C possono avere formato di frame diversi, o possono omettere puntatori telaio troppo:

4,3. JIT Symbols (Java, Node.js)

I programmi che dispongono di macchine virtuali (VM), come JVM Java e v8 del nodo, eseguono il proprio processore virtuale, che ha il proprio modo di eseguire funzioni e gestire stack. Se profili questi profili usando perf_events, vedrai i simboli per il motore VM .. perf_events ha il supporto JIT per risolvere questo problema, che richiede alla VM di mantenere un file /tmp/perf-PID.map per la conversione dei simboli.

Si noti che Java potrebbe non mostrare gli stack completi per cominciare, a causa dell'hotspot su x86 che omette il puntatore del frame (proprio come gcc). Nelle versioni più recenti (JDK 8u60 +), è possibile utilizzare l'opzione -XX:+PreserveFramePointer per correggere questo comportamento, ...

post sul blog del Gregg su Java e stack tracce: http://techblog.netflix.com/2015/07/java-in-flames.html ("puntatori fissaggio telaio" - fissa in qualche JDK8 versioni e in JDK9 con l'aggiunta di opzione all'avvio del programma)

Ora, le vostre domande:

Come si utility perf Linux capiscono impilare tracce?

perfutilità fondamentalmente (nelle prime versioni) analizza i dati appena tornato da sottosistema del kernel linux "perf_events" (oa volte "events"), cui si accede con syscall perf_event_open.Per analisi dello stack delle chiamate ci sono opzioni PERF_SAMPLE_CALLCHAIN/PERF_SAMPLE_STACK_USER:

sample_type PERF_SAMPLE_CALLCHAIN ​​ registra il callchain (stack backtrace).

  PERF_SAMPLE_STACK_USER (since Linux 3.7) 
       Records the user level stack, allowing stack unwinding. 

il kernel di Linux in modo nativo capire tracce dello stack?

Può comprendere (se implementato) e non può, a seconda dell'architettura della CPU. La funzione di campionamento (ottenendo/lettura stack di chiamate dal processo attivo) callchain è definito in parte indipendente dall'architettura del kernel come __weak con corpo vuoto:

http://lxr.free-electrons.com/source/kernel/events/callchain.c?v=4.4#L26

27 __weak void perf_callchain_kernel(struct perf_callchain_entry *entry, 
28         struct pt_regs *regs) 
29 { 
30 } 
31 
32 __weak void perf_callchain_user(struct perf_callchain_entry *entry, 
33         struct pt_regs *regs) 
34 { 
35 } 

In 4.4 kernel spazio utente callchain campionatore è ridefinito in parte dipende dall'architettura del kernel per x86/x86_64, ARC, SPARC, ARM/ARM64, Xtensa, Tilera TILE, PowerPC, Immaginazione Meta:

http://lxr.free-electrons.com/ident?v=4.4;i=perf_callchain_user

arch/x86/kernel/cpu/perf_event.c, line 2279 
arch/arc/kernel/perf_event.c, line 72 
arch/sparc/kernel/perf_event.c, line 1829 
arch/arm/kernel/perf_callchain.c, line 62 
arch/xtensa/kernel/perf_event.c, line 339 
arch/tile/kernel/perf_event.c, line 995 
arch/arm64/kernel/perf_callchain.c, line 109 
arch/powerpc/perf/callchain.c, line 490 
arch/metag/kernel/perf_callchain.c, line 59 

La lettura della catena di chiamate dallo stack utente può non essere banale per alcune architetture e/o per alcune modalità.

Quale architettura CPU si utilizza? Quali lingue e VM sono usate?

Dove posso leggere di più su come uno strumento è in grado di eseguire l'introspezione in tracce di stack di processi, anche se i processi sono scritti in lingue completamente diverse?

Puoi provare gdb e/o debugger per la lingua o backtrace function di libc o il supporto di sola lettura rilassarsi in libunwind (c'è local backtrace example in libunwind, show_backtrace()).

Possono avere un migliore supporto per l'analisi dei fotogrammi/una migliore integrazione con la macchina virtuale della lingua o con le informazioni di svolgimento. Se gdb (con il comando backtrace) o altri debugger non riescono a ottenere tracce di stack dal programma in esecuzione, potrebbe non esserci alcun modo di ottenere traccia di stack.

se possono ottenere traccia chiamata, ma non può perf (anche dopo la ricompilazione con -fno-omit-frame-pointer per C/C++), può essere possibile aggiungere supporto della combinazione di formato della trama architettura + in perf_events e perf.

Ci sono diversi blog con alcune informazioni su problemi backtracing generici e soluzioni:

supporto Nano per perf_events/perf:

+0

E informazioni su come perf programma l'interrupt di profilazione: http://stackoverflow.com/questions/28661430/how-does-a-system-wide-profiler-e-g-perf-correlate-counters-with-instructions/ – osgx

Problemi correlati