1818#
1919# Links:
2020# Home Page
21- # https://01.org/ pm-graph
21+ # https://www.intel.com/content/www/us/en/developer/topic-technology/open/ pm-graph/overview.html
2222# Source repo
2323# git@github.com:intel/pm-graph
2424#
6565from threading import Thread
6666from subprocess import call , Popen , PIPE
6767import base64
68+ import traceback
6869
6970debugtiming = False
7071mystarttime = time .time ()
@@ -86,7 +87,7 @@ def ascii(text):
8687# store system values and test parameters
8788class SystemValues :
8889 title = 'SleepGraph'
89- version = '5.12 '
90+ version = '5.13 '
9091 ansi = False
9192 rs = 0
9293 display = ''
@@ -236,7 +237,11 @@ class SystemValues:
236237 'msleep' : { 'args_x86_64' : {'time' :'%di:s32' }, 'ub' : 1 },
237238 'schedule_timeout' : { 'args_x86_64' : {'timeout' :'%di:s32' }, 'ub' : 1 },
238239 'udelay' : { 'func' :'__const_udelay' , 'args_x86_64' : {'loops' :'%di:s32' }, 'ub' : 1 },
239- 'usleep_range' : { 'args_x86_64' : {'min' :'%di:s32' , 'max' :'%si:s32' }, 'ub' : 1 },
240+ 'usleep_range' : {
241+ 'func' :'usleep_range_state' ,
242+ 'args_x86_64' : {'min' :'%di:s32' , 'max' :'%si:s32' },
243+ 'ub' : 1
244+ },
240245 'mutex_lock_slowpath' : { 'func' :'__mutex_lock_slowpath' , 'ub' : 1 },
241246 'acpi_os_stall' : {'ub' : 1 },
242247 'rt_mutex_slowlock' : {'ub' : 1 },
@@ -342,15 +347,21 @@ def vprint(self, msg):
342347 if self .verbose or msg .startswith ('WARNING:' ):
343348 pprint (msg )
344349 def signalHandler (self , signum , frame ):
345- if not self .result :
346- return
347350 signame = self .signames [signum ] if signum in self .signames else 'UNKNOWN'
348- msg = 'Signal %s caused a tool exit, line %d' % (signame , frame .f_lineno )
351+ if signame in ['SIGUSR1' , 'SIGUSR2' , 'SIGSEGV' ]:
352+ traceback .print_stack ()
353+ stack = traceback .format_list (traceback .extract_stack ())
354+ self .outputResult ({'stack' :stack })
355+ if signame == 'SIGUSR1' :
356+ return
357+ msg = '%s caused a tool exit, line %d' % (signame , frame .f_lineno )
358+ pprint (msg )
349359 self .outputResult ({'error' :msg })
360+ os .kill (os .getpid (), signal .SIGKILL )
350361 sys .exit (3 )
351362 def signalHandlerInit (self ):
352363 capture = ['BUS' , 'SYS' , 'XCPU' , 'XFSZ' , 'PWR' , 'HUP' , 'INT' , 'QUIT' ,
353- 'ILL' , 'ABRT' , 'FPE' , 'SEGV' , 'TERM' ]
364+ 'ILL' , 'ABRT' , 'FPE' , 'SEGV' , 'TERM' , 'USR1' , 'USR2' ]
354365 self .signames = dict ()
355366 for i in capture :
356367 s = 'SIG' + i
@@ -859,6 +870,11 @@ def verifyFtrace(self):
859870 # files needed for any trace data
860871 files = ['buffer_size_kb' , 'current_tracer' , 'trace' , 'trace_clock' ,
861872 'trace_marker' , 'trace_options' , 'tracing_on' ]
873+ # legacy check for old systems
874+ if not os .path .exists (self .tpath + 'trace' ):
875+ self .tpath = '/sys/kernel/debug/tracing/'
876+ if not os .path .exists (self .epath ):
877+ self .epath = '/sys/kernel/debug/tracing/events/power/'
862878 # files needed for callgraph trace data
863879 tp = self .tpath
864880 if (self .usecallgraph ):
@@ -911,6 +927,13 @@ def outputResult(self, testdata, num=0):
911927 if num > 0 :
912928 n = '%d' % num
913929 fp = open (self .result , 'a' )
930+ if 'stack' in testdata :
931+ fp .write ('Printing stack trace:\n ' )
932+ for line in testdata ['stack' ]:
933+ fp .write (line )
934+ fp .close ()
935+ self .sudoUserchown (self .result )
936+ return
914937 if 'error' in testdata :
915938 fp .write ('result%s: fail\n ' % n )
916939 fp .write ('error%s: %s\n ' % (n , testdata ['error' ]))
@@ -1980,7 +2003,7 @@ def newAction(self, phase, name, pid, parent, start, end, drv, htmlclass='', col
19802003 length = - 1.0
19812004 if (start >= 0 and end >= 0 ):
19822005 length = end - start
1983- if pid == - 2 or name not in sysvals . tracefuncs . keys () :
2006+ if pid >= - 2 :
19842007 i = 2
19852008 origname = name
19862009 while (name in list ):
@@ -2753,7 +2776,8 @@ def __init__(self, rowheight, scaleheight):
27532776 def createHeader (self , sv , stamp ):
27542777 if (not stamp ['time' ]):
27552778 return
2756- self .html += '<div class="version"><a href="https://01.org/pm-graph">%s v%s</a></div>' \
2779+ self .html += '<div class="version"><a href="https://www.intel.com/content/www/' + \
2780+ 'us/en/developer/topic-technology/open/pm-graph/overview.html">%s v%s</a></div>' \
27572781 % (sv .title , sv .version )
27582782 if sv .logmsg and sv .testlog :
27592783 self .html += '<button id="showtest" class="logbtn btnfmt">log</button>'
@@ -5238,12 +5262,16 @@ def addScriptCode(hf, testruns):
52385262 }
52395263 var info = dev[i].title.split(" ");
52405264 var pname = info[info.length-1];
5241- pd[pname] = parseFloat(info[info.length-3].slice(1));
5242- total[0] += pd[pname];
5265+ var length = parseFloat(info[info.length-3].slice(1));
5266+ if (pname in pd)
5267+ pd[pname] += length;
5268+ else
5269+ pd[pname] = length;
5270+ total[0] += length;
52435271 if(pname.indexOf("suspend") >= 0)
5244- total[tidx] += pd[pname] ;
5272+ total[tidx] += length ;
52455273 else
5246- total[tidx+1] += pd[pname] ;
5274+ total[tidx+1] += length ;
52475275 }
52485276 }
52495277 var devname = deviceTitle(this.title, total, cpu);
@@ -5262,7 +5290,7 @@ def addScriptCode(hf, testruns):
52625290 phases[i].style.left = left+"%";
52635291 phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";
52645292 left += w;
5265- var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id]+" ms<br></t4>";
5293+ var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id].toFixed(3) +" ms<br></t4>";
52665294 var pname = "<t3 style=\"font-size:"+fs2+"px\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";
52675295 phases[i].innerHTML = time+pname;
52685296 } else {
@@ -6742,6 +6770,7 @@ def printHelp():
67426770 ' -wifi If a wifi connection is available, check that it reconnects after resume.\n ' \
67436771 ' -wifitrace Trace kernel execution through wifi reconnect.\n ' \
67446772 ' -netfix Use netfix to reset the network in the event it fails to resume.\n ' \
6773+ ' -debugtiming Add timestamp to each printed line\n ' \
67456774 ' [testprep]\n ' \
67466775 ' -sync Sync the filesystems before starting the test\n ' \
67476776 ' -rs on/off Enable/disable runtime suspend for all devices, restore all after test\n ' \
@@ -7047,7 +7076,6 @@ def printHelp():
70477076 except :
70487077 doError ('No result file supplied' , True )
70497078 sysvals .result = val
7050- sysvals .signalHandlerInit ()
70517079 else :
70527080 doError ('Invalid argument: ' + arg , True )
70537081
@@ -7057,6 +7085,7 @@ def printHelp():
70577085 if (sysvals .usecallgraph and sysvals .useprocmon ):
70587086 doError ('-proc is not compatible with -f' )
70597087
7088+ sysvals .signalHandlerInit ()
70607089 if sysvals .usecallgraph and sysvals .cgskip :
70617090 sysvals .vprint ('Using cgskip file: %s' % sysvals .cgskip )
70627091 sysvals .setCallgraphBlacklist (sysvals .cgskip )
0 commit comments