Skip to content

Instantly share code, notes, and snippets.

@primiano
Created June 26, 2015 10:06
Show Gist options
  • Save primiano/950593eaeedb5fd52abe to your computer and use it in GitHub Desktop.
Save primiano/950593eaeedb5fd52abe to your computer and use it in GitHub Desktop.
Dump memory-infra traces
#!/usr/bin/env python
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import sys
def main():
METADATA_EVENT_PH = 'M'
MEMORY_INFRA_EVENT_PH = 'v'
events_grouped_by_id = {}
process_names = {}
process_labels = {}
if len(sys.argv) < 2:
print 'Usage: %s trace.json [Optional PID to filter]' % sys.argv[0]
sys.exit(1)
pid_filter = int(sys.argv[2]) if len(sys.argv) > 2 else None
with open(sys.argv[1]) as f:
data = json.load(f)
assert('traceEvents' in data), 'This doesn\'t look like a trace'
total = 0
for evt in data['traceEvents']:
if evt.get('ph') == METADATA_EVENT_PH:
if evt['name'] == 'process_name':
process_names[int(evt['pid'])] = evt['args']['name']
if evt['name'] == 'process_labels':
process_labels[int(evt['pid'])] = evt['args']['labels']
if evt.get('ph') != MEMORY_INFRA_EVENT_PH:
continue
total += 1
events_grouped_by_id.setdefault(evt['id'], [])
events_grouped_by_id[evt['id']].append(evt)
global_memory_events_sorted_by_time = sorted(events_grouped_by_id.itervalues(), key=lambda evt:evt[0]['ts'])
start_ts = 0
total_global_dumps = len(global_memory_events_sorted_by_time)
global_dump_idx = 0
for pid in process_names.iterkeys():
process_names[pid] += ' ' + process_labels.get(pid, '')
print 'Dumping %d global memory events, %d total processes' % (total_global_dumps, len(process_names))
print 'Process map:'
for pid, process_name in process_names.iteritems():
print ' PID: %4d : %s ' % (pid, process_name)
print '\n\n\n'
for events in global_memory_events_sorted_by_time:
# events is a list of events (one per process) for the same global dump.
global_dump_idx += 1
ts = min(e['ts'] for e in events)
start_ts = ts if start_ts == 0 else start_ts
relative_ts = (ts - start_ts) / 1000000.0
has_mmaps = any('process_mmaps' in e['args']['dumps'] for e in events)
print 'T=%.2f s. %s' % (relative_ts, '[w/ mmaps]' if has_mmaps else '')
for event in events:
pid = event['pid']
if pid_filter and pid_filter != pid:
continue
print ' [%d/%d] Process %d (%s)' % (global_dump_idx, total_global_dumps, pid, process_names.get(pid))
allocator_dumps = event['args']['dumps']['allocators']
for dump_name, dump in sorted(allocator_dumps.iteritems(), key=lambda kv:kv[0]):
size = int(dump['attrs']['size']['value'], 16) if 'size' in dump['attrs'] else 0
print ' %-80s size: %s' % (dump_name, size)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment