转自:http://www.brendangregg.com/blog/2017-07-30/coloring-flamegraphs-code-type.html

I recently improved flame graph code coloring. If you're automating or implementing flame graphs, this is a small detail that may interest you. (For an intro to flame graphs, see my website and github.)

First, a confession. Code-type coloring was a regex hack that took five minutes. In late 2014 I was modifying the JDK to preserve the frame pointer so that traditional stack walkers and profilers would work (an example of the problem is here, where Java methods lack ancestry). After I fixed the frame pointer, profiling Java looked like this (SVG):

It worked! Java methods now had ancesty (stack depth), and appear as towers.

I was delighted and showed my colleagues straight away. Amer Ather, another performance engineer at Netflix, suggested I color the Java and kernel frames differently. He was only back at his desk for five minutes when I called him back (SVG):

Done. (I also stripped the extra L from Java symbols.)

My hack was the following eight lines of code:

        if (defined $type and $type eq "java") {
if ($name =~ /::/) { # C++
$type = "yellow";
} elsif ($name =~ m:/:) { # Java (match "/" in path)
$type = "green"
} else { # system
$type = "red";
}

The "java" $type is from the command line option: --color=java. The $name is the function name. Here are some sample function names:

  • Java
    io/netty/channel/nio/NioEventLoop;.run
    org/mozilla/classfile/ClassFileWriter;.addLoadConstant
  • C++JavaCalls::call_helper
    JavaThread::thread_main_inner
  • Ctcp_v4_do_rcv
    start_thread
    write

If you cast your regular expression eye over these, you'll quickly see patterns. If it contains "::" it's C++, "/" it's Java, else it's C. And that's what I coded.

It mostly worked. But I've noticed the odd case where it gets things wrong. Sometimes the profiled Java symbols use "." instead of "/" as a delimiter. Or, somehow, I have Java methods that lack any package delimiter, so were colored red. I had similar issues with JIT'd code for Node.js.

Revisiting how flame graphs for Linux perf are generated (full instructions in Java Flame Graphs):

perf record -F 49 -a -g -- sleep 30; ./jmaps
perf script | ./stackcollapse-perf.pl | grep -v cpu_idle | ./flamegraph.pl --color=java > out.svg

It's beginning with the output of perf script (later perf versions added a way to emit a folded summary directly). Here is some truncated perf script output:

java  4811 cpu-clock:
ffffffff8100122a hypercall_page ([kernel.kallsyms])
ffffffff8100aca2 check_events ([kernel.kallsyms])
ffffffff8104dffe __wake_up_sync_key ([kernel.kallsyms])
ffffffff8152f86e sock_def_readable ([kernel.kallsyms])
[...]
ffffffff81662142 system_call_fastpath ([kernel.kallsyms])
7f62aadf2f7d write (/lib/x86_64-linux-gnu/libc-2.15.so)
7f62961a5e8b Lsun/nio/ch/FileDispatcherImpl;.write0(Ljava/io/FileDescriptor;JI)I (/tmp/perf-4637.map)
7f629619dd64 Lsun/nio/ch/SocketDispatcher;.write(Ljava/io/FileDescriptor;JI)I (/tmp/perf-4637.map)
7f62961b3330 Lsun/nio/ch/IOUtil;.writeFromNativeBuffer(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;JLsun/nio/ch/NativeDispatcher;)I (/tmp/perf-4637.map)
[...]
7f62aa3b1618 JavaThread::thread_main_inner() (/mnt/openjdk8/build/linux-x86_64-normal-server-release/jdk/lib/amd64/server/libjvm.so)
7f62aa3b186c JavaThread::run() (/mnt/openjdk8/build/linux-x86_64-normal-server-release/jdk/lib/amd64/server/libjvm.so)
7f62aa272bf2 java_start(Thread*) (/mnt/openjdk8/build/linux-x86_64-normal-server-release/jdk/lib/amd64/server/libjvm.so)
7f62aa8f2e9a start_thread (/lib/x86_64-linux-gnu/libpthread-2.15.so)

The stackcollapse-perf.pl tool plucks out the symbol name (second column) and discards everything else. But the last column – the segment printed in ( ) – provides more details for identifying code types. Eg:

  • [kernel.kallsyms]: kernel code (I could also match the addr vs the kernel base address for this)
  • /tmp/perf-PID.map: JIT'd code (Java, Node.js, ...)

This is what I made use of recently, by adding an --all option to stackcollapse-perf.pl to turn on all annotations. Annotations are inspired by the "[k]" annotations seen in perf report --stdiooutput. I append them after the function name, so tcp_sengmsg becomes tcp_sengmsg_[k], and that annotation is used and then stripped by flamegraph.pl.

Annontation suffixes:

  • _[k]: kernel
  • _[j]: JIT
  • _[i]: inlined function
  • _[w]: waker stack (for offwake or chain graphs)

Making use of both annotations and pattern matching, the "java" palette is now:

  • green: JIT (Java, Node.js, ...)
  • aqua: inlined
  • yellow: C++
  • orange: kernel
  • red: native (user-level)

If you're automating flame graphs using my original tools, you might want to consider adding --all to the normal workflow for annotations. These are currently used by the "java" and "js" palettes. Eg:

perf record -F 49 -a -g -- sleep 30; ./jmaps
perf script | ./stackcollapse-perf.pl --all | grep -v cpu_idle | ./flamegraph.pl --color=java > out.svg

If you are using a different profiler (not Linux perf), you might want to consider enhancing its stackcollapse program to have an option to turn on annotations (or I can do it next time I use them). If you are implementing your own flame graph software, you might want to add similar color hues for code types.

Finally, it should be clear that changing the hue of code based on a regex is a trivial change to flamegraph.pl. You could add custom rules to your version to highlight your team's code, for example.

Coloring Flame Graphs: Code Hues的更多相关文章

  1. New JVM Option Enables Generation of Mixed-Mode Flame Graphs

    转自 https://www.infoq.com/news/2015/08/JVM-Option-mixed-mode-profiles Java has added a new launch opt ...

  2. tunning-Instruments and Flame Graphs

    On mac os, programs may need Instruments to tuning, and when you face too many probe messages, you'l ...

  3. Flame Graphs

    http://www.brendangregg.com/flamegraphs.html Flame graphs are a visualization of profiled software, ...

  4. 火焰图(Flame Graphs)的安装和基本用法

    火焰图(Flame Graphs) 一.概述: 火焰图(flame graph)是性能分析的利器,通过它可以快速定位性能瓶颈点. perf 命令(performance 的缩写)是 Linux 系统原 ...

  5. 使用Flame Graph进行系统性能分析

    关键词:Flame Graph.perf.perl. FlameGraph是由BrendanGregg开发的一款开源可视化性能分析工具,形象的成为火焰图. 从底向上像火苗一样逐渐变小,也反映了相互之间 ...

  6. linux perf and tracer ,java Flame Graph

    http://www.brendangregg.com/flamegraphs.html http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/rev/e826 ...

  7. 【Xamarin 跨平台机制原理剖析】

    原文:[Xamarin 跨平台机制原理剖析] [看了请推荐,推荐满100后,将发补丁地址] Xamarin项目从喊口号到现在,好几个年头了,在内地没有火起来,原因无非有三,1.授权费贵 2.贵 3.原 ...

  8. Choosing a Linux Tracer ------Brendan Gregg's Blog

    home Choosing a Linux Tracer (2015) 08 Jul 2015 Linux Tracing is Magic! A tracer is an advanced perf ...

  9. 【Xamain 跨平台机制原理剖析】

    原文:[Xamain 跨平台机制原理剖析] [看了请推荐,推荐满100后,将发补丁地址] Xamarin项目从喊口号到现在,好几个年头了,在内地没有火起来,原因无非有三,1.授权费贵 2.贵 3.原生 ...

随机推荐

  1. ASP.NET MVC 认证模块报错:“System.Configuration.Provider.ProviderException: 未启用角色管理器功能“

    新建MVC4项目的时候 选 Internet 应用程序的话,出来的示例项目就自带了默认的登录认证等功能.如果选空或者基本,就没有. 如果没有,现在又想加进去,怎么办呢? 抄啊.将示例项目的代码原原本本 ...

  2. SpringMVC中的 --- 异常处理

    系统异常处理器SimpleMappingExceptionResolver 处理器方法执行过程中,可能会发生异常,不想看到错误黄页,想看到一个友好的错误提示页. 自定义异常处理器 使用异常处理注解

  3. luogu1052 过河

    题目大意 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...

  4. hdu 1532 Drainage Ditches(最大流)

                                                                                            Drainage Dit ...

  5. iOS开发之KVC全解

    一  KVC的基本概念 1.KVC是Key Value Coding的缩写,意思是键值编码. 在iOS中,提供了一种方法通过使用属性的名称(也就是Key)来间接访问对象属性的方法,这个方法可以不通过g ...

  6. Thinkpad E450c开启Intel virtual technology

    1.重启系统,一直按F12,进入系统设置后,按tab进入App Menu选项卡,选择Setup按回车进入BIOS设置 2.移动到Security选项 3.移动到Virtualization,按ente ...

  7. B. Sereja and Suffixes(cf)

    http://codeforces.com/problemset/problem/368/B B. Sereja and Suffixes time limit per test 1 second m ...

  8. git add -A (用该命令添加文件时报错)

    前言 最近在学着不使用github客户端,而直接用git命令上传代码至github,当使用命令 git add -A 添加所有项目文件时报错    老实说我是蒙蔽的,因为从来没有遇到过这个错,确认输入 ...

  9. BZOJ 2431 逆序对数列 DP

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec Memory Limit: 128 MB Description 对于一个数列{ai},如果有i< j且ai> ...

  10. java线程中断

    public void Thread.interrupt() // 无返回值 public boolean Thread.isInterrupted() // 有返回值 public static b ...