apptrace_proc.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/env python
  2. #
  3. import argparse
  4. import struct
  5. import sys
  6. class bcolors:
  7. HEADER = '\033[95m'
  8. OKBLUE = '\033[94m'
  9. OKGREEN = '\033[92m'
  10. WARNING = '\033[93m'
  11. FAIL = '\033[91m'
  12. ENDC = '\033[0m'
  13. BOLD = '\033[1m'
  14. UNDERLINE = '\033[4m'
  15. def main():
  16. ESP32_TRACE_BLOCK_HDR_SZ = 8
  17. ESP32_TRACE_BLOCK_TASK_IDX = 0
  18. ESP32_TRACE_BLOCK_TS_IDX = 1
  19. ESP32_TRACE_BLOCK_DATA_IDX = 2
  20. parser = argparse.ArgumentParser(description='ESP32 App Trace Parse Tool')
  21. parser.add_argument('file', help='Path to app trace file', type=str)
  22. parser.add_argument('--print-tasks', '-p', help='Print tasks', action='store_true')
  23. parser.add_argument('--print-details', '-d', help='Print detailed stats', action='store_true')
  24. parser.add_argument('--no-errors', '-n', help='Do not print errors', action='store_true')
  25. parser.add_argument('--block-len', '-b', help='Block length', type=int, default=1024)
  26. args = parser.parse_args()
  27. print "===================================================================="
  28. try:
  29. ftrc = open(args.file, 'rb')
  30. except IOError as e:
  31. print "Failed to open trace file (%s)!" % e
  32. sys.exit(2)
  33. passed = True
  34. off = 0
  35. data_stats = {}
  36. last_ts = None
  37. tot_discont = 0
  38. while True:
  39. #ftrc.seek(off)
  40. task = None
  41. ts = 0
  42. trc_buf = ftrc.read(args.block_len)
  43. if len(trc_buf) == 0:
  44. # print 'EOF'
  45. break
  46. trc_data = struct.unpack('<LL%sB' % (len(trc_buf) - ESP32_TRACE_BLOCK_HDR_SZ), trc_buf)
  47. if len(trc_data):
  48. # print "%x %x, len %d" % (trc_data[0], trc_data[1], len(trc_data) - 2)
  49. # print trc_data[2:]
  50. # sys.exit(0)
  51. task = trc_data[ESP32_TRACE_BLOCK_TASK_IDX]
  52. ts = trc_data[ESP32_TRACE_BLOCK_TS_IDX]
  53. # print ts
  54. if last_ts and last_ts >= ts:
  55. # print "Global TS discontinuity %x -> %x, task %x, stamp %x at %x" % (last_ts, ts, task, data_stats[task]['stamp'], off)
  56. if args.print_details:
  57. print "Global TS discontinuity %x -> %x, task %x at %x" % (last_ts, ts, task, off)
  58. # tot_discont += 1
  59. # passed = False
  60. last_ts = ts
  61. if not task in data_stats:
  62. print "%x: NEW TASK" % task
  63. data_stats[task] = {'stamp' : trc_data[ESP32_TRACE_BLOCK_DATA_IDX], 'last_ts' : ts, 'count' : 1, 'discont_offs' : [], 'inv_stamps_offs' : []}
  64. else:
  65. if data_stats[task]['last_ts'] == ts:
  66. print "Task TS discontinuity %x -> %x, task %x, stamp %x at %x" % (last_ts, ts, task, data_stats[task]['stamp'], off)
  67. data_stats[task]['discont_offs'].append(off)
  68. tot_discont += 1
  69. passed = False
  70. data_stats[task]['last_ts'] = ts
  71. data_stats[task]['count'] += 1
  72. if len(trc_data) > ESP32_TRACE_BLOCK_DATA_IDX:
  73. # print "DATA = %x %x %x %x" % (trc_data[-4], trc_data[-3], trc_data[-2], trc_data[-1])
  74. if args.print_tasks:
  75. print "Task[%d] %x, ts %08x, stamp %x" % (off/args.block_len, task, ts, trc_data[ESP32_TRACE_BLOCK_DATA_IDX])
  76. else:
  77. print "%x: NO DATA" % task
  78. else:
  79. print "Failed to unpack data!"
  80. sys.exit(2)
  81. # check data
  82. for i in range(ESP32_TRACE_BLOCK_DATA_IDX, len(trc_data)):
  83. if trc_data[i] != data_stats[task]['stamp']:
  84. if not args.no_errors:
  85. print "Invalid stamp %x->%x at %x, task %x" % (data_stats[task]['stamp'], trc_data[i], off + ESP32_TRACE_BLOCK_HDR_SZ + i, task)
  86. passed = False
  87. data_stats[task]['stamp'] = trc_data[i]
  88. data_stats[task]['inv_stamps_offs'].append(off)
  89. # break
  90. if len(trc_buf) < args.block_len:
  91. print 'Last block (not full)'
  92. break
  93. if data_stats[task]['stamp'] != None:
  94. data_stats[task]['stamp'] = (data_stats[task]['stamp'] + 1) & 0xFF
  95. # print "stamp=%x" % data_stats[task][ESP32_TRACE_STAMP_IDX]
  96. off += args.block_len
  97. ftrc.close()
  98. print "===================================================================="
  99. print "Trace size %d bytes, discont %d\n" % (off, tot_discont)
  100. for t in data_stats:
  101. print "Task %x. Total count %d. Inv stamps %d. TS Discontinuities %d." % (t, data_stats[t]['count'], len(data_stats[t]['inv_stamps_offs']), len(data_stats[t]['discont_offs']))
  102. if args.print_details:
  103. print 'Invalid stamps offs: [{}]'.format(', '.join(hex(x) for x in data_stats[t]['inv_stamps_offs']))
  104. print 'TS Discontinuities offs: [{}]'.format(', '.join(hex(x) for x in data_stats[t]['discont_offs']))
  105. print "\n"
  106. if passed:
  107. print "Data - OK"
  108. else:
  109. print "Data - FAILED!"
  110. if __name__ == '__main__':
  111. main()