1+ import sys
12import os
23try :
34 from urlparse import urlparse
1617import elftools .elf .constants as elfconst
1718
1819
20+ def clock ():
21+ if sys .version_info >= (3 , 3 ):
22+ return time .process_time ()
23+ else :
24+ return time .clock ()
25+
26+
1927def addr2line (toolchain , elf_path , addr ):
2028 """
2129 Creates trace reader.
@@ -170,12 +178,12 @@ def read(self, sz):
170178 see Reader.read()
171179 """
172180 data = b''
173- start_tm = time . clock ()
181+ start_tm = clock ()
174182 while not self .need_stop :
175183 data += self .trace_file .read (sz - len (data ))
176184 if len (data ) == sz :
177185 break
178- if self .timeout != - 1 and time . clock () >= start_tm + self .timeout :
186+ if self .timeout != - 1 and clock () >= start_tm + self .timeout :
179187 raise ReaderTimeoutError (self .timeout , sz )
180188 if self .need_stop :
181189 raise ReaderShutdownRequest ()
@@ -192,17 +200,17 @@ def get_pos(self):
192200 """
193201 return self .trace_file .tell ()
194202
195- def readline (self ):
203+ def readline (self , linesep = os . linesep ):
196204 """
197205 see Reader.read()
198206 """
199207 line = ''
200- start_tm = time . clock ()
208+ start_tm = clock ()
201209 while not self .need_stop :
202210 line += self .trace_file .readline ().decode ("utf-8" )
203- if line .endswith (os . linesep ):
211+ if line .endswith (linesep ):
204212 break
205- if self .timeout != - 1 and time . clock () >= start_tm + self .timeout :
213+ if self .timeout != - 1 and clock () >= start_tm + self .timeout :
206214 raise ReaderTimeoutError (self .timeout , 1 )
207215 if self .need_stop :
208216 raise ReaderShutdownRequest ()
@@ -213,12 +221,12 @@ def forward(self, sz):
213221 see Reader.read()
214222 """
215223 cur_pos = self .trace_file .tell ()
216- start_tm = time . clock ()
224+ start_tm = clock ()
217225 while not self .need_stop :
218226 file_sz = os .path .getsize (self .trace_file_path )
219227 if file_sz - cur_pos >= sz :
220228 break
221- if self .timeout != - 1 and time . clock () >= start_tm + self .timeout :
229+ if self .timeout != - 1 and clock () >= start_tm + self .timeout :
222230 raise ReaderTimeoutError (self .timeout , sz )
223231 if self .need_stop :
224232 raise ReaderShutdownRequest ()
@@ -351,6 +359,34 @@ def reader_create(trc_src, tmo):
351359 return None
352360
353361
362+ class TraceEvent :
363+ """
364+ Base class for all trace events.
365+ """
366+ def __init__ (self , name , core_id , evt_id ):
367+ self .name = name
368+ self .ctx_name = 'None'
369+ self .in_irq = False
370+ self .core_id = core_id
371+ self .id = evt_id
372+ self .ts = 0
373+ self .params = {}
374+
375+ @property
376+ def ctx_desc (self ):
377+ if self .in_irq :
378+ return 'IRQ "%s"' % self .ctx_name
379+ return 'task "%s"' % self .ctx_name
380+
381+ def to_jsonable (self ):
382+ res = self .__dict__
383+ params = {}
384+ for p in self .params :
385+ params .update (self .params [p ].to_jsonable ())
386+ res ['params' ] = params
387+ return res
388+
389+
354390class TraceDataProcessor :
355391 """
356392 Base abstract class for all trace data processors.
@@ -432,17 +468,21 @@ def get_str_from_elf(felf, str_addr):
432468 string
433469 string or None if it was not found
434470 """
435- tgt_str = ""
471+ tgt_str = ''
436472 for sect in felf .iter_sections ():
437473 if sect ['sh_addr' ] == 0 or (sect ['sh_flags' ] & elfconst .SH_FLAGS .SHF_ALLOC ) == 0 :
438474 continue
439475 if str_addr < sect ['sh_addr' ] or str_addr >= sect ['sh_addr' ] + sect ['sh_size' ]:
440476 continue
441477 sec_data = sect .data ()
442478 for i in range (str_addr - sect ['sh_addr' ], sect ['sh_size' ]):
443- if sec_data [i ] == "\0 " :
479+ if type (sec_data ) is str :
480+ ch = sec_data [i ]
481+ else :
482+ ch = str (chr (sec_data [i ]))
483+ if ch == '\0 ' :
444484 break
445- tgt_str += sec_data [ i ]
485+ tgt_str += ch
446486 if len (tgt_str ) > 0 :
447487 return tgt_str
448488 return None
@@ -488,9 +528,8 @@ def get_message(self, felf):
488528 fmt_str = get_str_from_elf (felf , self .fmt_addr )
489529 if not fmt_str :
490530 raise LogTraceParseError ('Failed to find format string for 0x%x' % self .fmt_addr )
491- i = 0
492531 prcnt_idx = 0
493- while i < len (self .args ):
532+ for i , arg in enumerate (self .args ):
494533 prcnt_idx = fmt_str .find ('%' , prcnt_idx , - 2 ) # TODO: check str ending with %
495534 if prcnt_idx == - 1 :
496535 break
@@ -502,7 +541,6 @@ def get_message(self, felf):
502541 self .args [i ] = arg_str
503542 else :
504543 self .args [i ] = '<None>'
505- i += 1
506544 fmt_str = fmt_str .replace ('%p' , '%x' )
507545 return fmt_str % tuple (self .args )
508546
@@ -591,66 +629,63 @@ class HeapTraceEvent:
591629 """
592630 Heap trace event.
593631 """
594- def __init__ (self , ctx_name , in_irq , core_id , ts , alloc , size , addr , callers , toolchain = '' , elf_path = '' ):
632+ def __init__ (self , trace_event , alloc , toolchain = '' , elf_path = '' ):
595633 """
596634 Constructor.
597635
598636 Parameters
599637 ----------
600- ctx_name : string
601- name of event context (task or IRQ name)
602- in_irq : bool
603- True if event has been generated in IRQ context, otherwise False
604- core_id : int
605- core which generated the event
606- ts : float
607- event timestamp
638+ sys_view_event : TraceEvent
639+ trace event object related to this heap event
608640 alloc : bool
609641 True for allocation event, otherwise False
610- size : int
611- size of allocation; has no meaning for de-allocation event
612- addr : int
613- address of allocation/de-allocation
614- callers : list
615- list of callers (callstack) for event
616642 toolchain_pref : string
617643 toolchain prefix to retrieve source line locations using addresses
618644 elf_path : string
619645 path to ELF file to retrieve format strings for log messages
620646 """
621- self .ctx_name = ctx_name
622- self .in_irq = in_irq
623- self .core_id = core_id
624- self .ts = ts
647+ self .trace_event = trace_event
625648 self .alloc = alloc
626- self .size = size
627- self .addr = addr
628- self .callers = callers
629649 self .toolchain = toolchain
630650 self .elf_path = elf_path
651+ if self .alloc :
652+ self .size = self .trace_event .params ['size' ].value
653+ else :
654+ self .size = None
655+
656+ @property
657+ def addr (self ):
658+ return self .trace_event .params ['addr' ].value
659+
660+ @property
661+ def callers (self ):
662+ return self .trace_event .params ['callers' ].value
631663
632664 def __repr__ (self ):
633665 if len (self .toolchain ) and len (self .elf_path ):
634666 callers = os .linesep
635- for addr in self .callers :
667+ for addr in self .trace_event .params ['callers' ].value :
668+ if addr == 0 :
669+ break
636670 callers += '{}' .format (addr2line (self .toolchain , self .elf_path , addr ))
637671 else :
638672 callers = ''
639- for addr in self .callers :
673+ for addr in self .trace_event .params ['callers' ].value :
674+ if addr == 0 :
675+ break
640676 if len (callers ):
641677 callers += ':'
642678 callers += '0x{:x}' .format (addr )
643- if self .in_irq :
644- ctx_desc = 'IRQ "%s"' % self .ctx_name
645- else :
646- ctx_desc = 'task "%s"' % self .ctx_name
647679 if self .alloc :
648- return "[{:.9f}] HEAP: Allocated {:d} bytes @ 0x{:x} from {} on core {:d} by: {}" .format (self .ts , self .size ,
649- self .addr , ctx_desc ,
650- self .core_id , callers )
680+ return "[{:.9f}] HEAP: Allocated {:d} bytes @ 0x{:x} from {} on core {:d} by: {}" .format (self .trace_event .ts ,
681+ self .size , self .addr ,
682+ self .trace_event .ctx_desc ,
683+ self .trace_event .core_id ,
684+ callers )
651685 else :
652- return "[{:.9f}] HEAP: Freed bytes @ 0x{:x} from {} on core {:d} by: {}" .format (self .ts , self .addr , ctx_desc ,
653- self .core_id , callers )
686+ return "[{:.9f}] HEAP: Freed bytes @ 0x{:x} from {} on core {:d} by: {}" .format (self .trace_event .ts ,
687+ self .addr , self .trace_event .ctx_desc ,
688+ self .trace_event .core_id , callers )
654689
655690
656691class BaseHeapTraceDataProcessorImpl :
0 commit comments