ó õsac@s‰dZddlZddlZdd d„ƒYZdefd„ƒYZdefd„ƒYZd „Zd „Ze d kr…eƒndS( sH Copyright 2008 (c) Frederic Weisbecker Licensed under the terms of the GNU GPL License version 2 This script parses a trace provided by the function tracer in kernel/trace/trace_functions.c The resulted trace is processed into a tree to produce a more human view of the call stack by drawing textual but hierarchical tree of calls. Only the functions's names and the the call time are provided. Usage: Be sure that you have CONFIG_FUNCTION_TRACER # mount -t debugfs nodev /sys/kernel/debug # echo function > /sys/kernel/debug/tracing/current_tracer $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func Wait some times but not too much, the script is a bit slow. Break the pipe (Ctrl + Z) $ scripts/draw_functrace.py < raw_trace_func > draw_functrace Then you have your drawn trace in draw_functrace iÿÿÿÿNtCallTreecBsGeZdZdZddd„Zd„Zd„Zd„Zd„Z RS(sÕ This class provides a tree representation of the functions call stack. If a function has no parent in the kernel (interrupt, syscall, kernel thread...) then it is attached to a virtual parent called ROOT. cCsC||_||_|dkr-tj|_n ||_g|_dS(N(t_funct_timetNoneRtROOTt_parentt _children(tselftfuncttimetparent((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyt__init__#s     cCs&t|||ƒ}|jj|ƒ|S(s¦ If a function calls another one, call this method to insert it into the tree at the appropriate place. @return: A reference to the newly created child node. (RRtappend(RRtcalltimetchild((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pytcalls,scCs`|}x+|tjkr3|j|kr3|j}q W|tjkr\tjj|dƒ}|S|S(sÇ Retrieve the last parent of the current node that has the name given by func. If this function is not on a parent, then create it as new child of root @return: A reference to the parent. N(RRRRRR(RRttreeR((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyt getParent5s! cCs|jdtƒS(Nt(t_CallTree__toStringtTrue(R((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyt__repr__CscCsë|jdk r+d||j|jf}nd||jf}d}|r[|d d}nx‰|t|jƒkræ|t|jƒdkr´|d|j|j|dtƒ7}n%|d|j|j|dtƒ7}|d7}q^W|S( Ns%s----%s (%s) s %s----%s iiÿÿÿÿt is%ss |(RRRtlenRRtFalseR(Rtbrancht lastChildtsti((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyt __toStringFsN( t__name__t __module__t__doc__RRR RRRR(((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyRs  tBrokenLineExceptioncBseZdZRS(syIf the last line is not complete because of the pipe breakage, we want to stop the processing and ignore this line. (RRR (((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyR!YstCommentLineExceptioncBseZdZRS(sY If the line is a comment (as in the beginning of the trace file), just ignore it. (RRR (((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyR"_scCss|jƒ}|jdƒr$t‚ntjd|ƒ}|dkrKt‚n|jdƒ|jdƒ|jdƒfS(Nt#s"[^]]+?\] +([0-9.]+): (\w+) <-(\w+)iii(tstript startswithR"tretmatchRR!tgroup(tlinetm((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyt parseLinefs    cCs tdddƒt_tj}xstjD]h}yt|ƒ\}}}Wn%tk r[Pntk rnq(nX|j|ƒ}|j ||ƒ}q(WtjGHdS(NsRoot (Nowhere)( RRRtsyststdinR+R!R"RR(RR)R tcalleetcaller((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pytmainps   t__main__(( R R,R&Rt ExceptionR!R"R+R0R(((sN/usr/src/kernels/3.10.0-1160.41.1.el7.x86_64/scripts/tracing/draw_functrace.pyts>