Sha*_*baz 13 linux-kernel perf flamegraph
Brendan Gregg使用Linux的perf实用程序为c/c ++,jvm代码,nodejs代码等生成火焰图.
Linux内核本身是否了解堆栈跟踪?在哪里可以阅读更多关于工具如何能够反省到流程的堆栈跟踪,即使流程是用完全不同的语言编写的?
osg*_*sgx 26
关于堆栈跟踪的简短介绍perf由Gregg提供:http:
//www.brendangregg.com/perf.html
4.4堆栈跟踪
始终使用帧指针进行编译.省略框架指针是一种破坏调试器的恶意编译器优化,遗憾的是,它通常是默认的.如果没有它们,您可能会看到perf_events中的不完整堆栈...有两种方法可以解决此问题:使用dwarf数据展开堆栈或返回帧指针.
侏儒
从大约3.9内核开始,perf_events支持在用户级堆栈中丢失帧指针的解决方法:libunwind,它使用dwarf.这可以使用"-g dwarf"启用....编译器优化(
-O2),在这种情况下省略了帧指针....重新编译..用-fno-omit-frame-pointer:
非C风格的语言可能有不同的帧格式,或者也可能省略帧指针:
4.3.JIT符号(Java,Node.js)
具有虚拟机(VM)的程序(如Java的JVM和节点的v8)执行自己的虚拟处理器,该处理器具有执行功能和管理堆栈的方式.如果使用perf_events对这些进行分析,您将看到VM引擎的符号.perf_events具有JIT支持来解决此问题,这需要VM维护
/tmp/perf-PID.map用于符号转换的文件.请注意,Java可能不会显示完整的堆栈,因为x86上的热点省略了帧指针(就像gcc一样).在较新的版本(JDK 8u60 +)上,您可以使用该
-XX:+PreserveFramePointer选项来修复此行为,...
Gregg关于Java和堆栈跟踪的博客文章:http: //techblog.netflix.com/2015/07/java-in-flames.html("Fixing Frame Pointers" - 通过添加选项在一些JDK8版本和JDK9中修复程序开始)
现在,您的问题:
linux的perf实用程序如何理解堆栈跟踪?
perf 实用程序基本上(在早期版本中)只解析从linux内核的子系统" perf_events"(或有时" events")返回的数据,用syscall访问perf_event_open.对于调用堆栈跟踪,有选项PERF_SAMPLE_CALLCHAIN/ PERF_SAMPLE_STACK_USER:
sample_type PERF_SAMPLE_CALLCHAIN记录调用链(堆栈回溯).
PERF_SAMPLE_STACK_USER (since Linux 3.7)
Records the user level stack, allowing stack unwinding.
Run Code Online (Sandbox Code Playgroud)
Linux内核本身是否了解堆栈跟踪?
它可能理解(如果实现),也可能不理解,具体取决于您的cpu架构.采样(从实时进程获取/读取调用堆栈)调用链的功能在内核的__weak与体系结构无关的部分中定义为空体:
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 }
Run Code Online (Sandbox Code Playgroud)
在4.4内核中,用户空间中的callchain采样器在x86/x86_64,ARC,SPARC,ARM/ARM64,Xtensa,Tilera TILE,PowerPC,Imagination 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
Run Code Online (Sandbox Code Playgroud)
对于某些体系结构和/或某些模式,从用户堆栈读取调用链可能不是微不足道的.
你使用什么CPU架构?使用什么语言和VM?
在哪里可以阅读更多关于工具如何能够反省到流程的堆栈跟踪,即使流程是用完全不同的语言编写的?
您可以尝试gdb和/或语言或调试器backtrace功能的libc或支持只读在libunwind平仓(有在libunwind当地回溯例如,show_backtrace()).
他们可能更好地支持框架解析/更好地与语言的虚拟机或展开信息集成.如果gdb(带backtrace命令)或其他调试器无法从运行程序中获取堆栈跟踪,则可能根本无法获得堆栈跟踪.
如果他们能得到呼叫跟踪,但perf不能(即使使用后重新编译-fno-omit-frame-pointer为C/C++),有可能添加支持架构+帧格式的这种组合的成perf_events和perf.
有几个博客提供有关通用回溯问题和解决方案的一些信息:
__builtin_return_address(N)与glibc的backtrace()对比libunwind的本地回溯矮人对perf_events/的支持perf:
| 归档时间: |
|
| 查看次数: |
6382 次 |
| 最近记录: |