2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Symbolizes and prints live objects as recorded by tcmalloc's
7 HeapProfilerDumpLiveObjects.
19 tools/tcmalloc/print-live-objects.py out/Debug/chrome leaks.dmp
22 def LoadDump(dump_file
):
25 r
"^\s*1:\s*(\d+)\s*\[\s*1:\s*\d+\]\s*@(0x[a-f0-9]+)((\s+0x[a-f0-9]+)*)$")
27 with
open(dump_file
) as f
:
30 matches
= leakfmt
.match(line
)
32 print "%s: could not parse line %d, skipping" % (dump_file
, line_no
)
34 trace
= { "size": int(matches
.group(1)),
35 "address": matches
.group(2),
36 "frames": matches
.group(3).strip().split(" ")}
41 def Symbolize(binary
, traces
):
44 for frame
in trace
["frames"]:
46 addr_file
, addr_filename
= tempfile
.mkstemp()
47 for addr
in addresses
:
48 os
.write(addr_file
, "%s\n" % addr
)
50 syms
= subprocess
.Popen([
51 "addr2line", "-f", "-C", "-e", binary
, "@%s" % addr_filename
],
52 stdout
=subprocess
.PIPE
).communicate()[0].strip().split("\n")
55 for address
, symbol
, location
in zip(addresses
, syms
[::2], syms
[1::2]):
56 if location
!= "??:0":
57 filename
, line
= location
.split(":")
58 filename
= os
.path
.realpath(filename
)[len(cwd
)+1:]
59 location
= "%s:%s" % (filename
, line
)
60 table
[address
] = { "name": symbol
, "location": location
}
63 for frame
in trace
["frames"]:
64 frames
.append(table
[frame
])
65 trace
["frames"] = frames
69 if sys
.platform
!= 'linux2':
70 print 'print-live-objects.py requires addr2line only present on Linux.'
77 traces
= LoadDump(argv
[2])
78 Symbolize(argv
[1], traces
)
81 print "No leaks found!"
83 for trace
in sorted(traces
, key
=lambda x
: -x
["size"]):
84 print "Leak of %d bytes at address %s" % (trace
["size"], trace
["address"])
85 for frame
in trace
["frames"]:
86 print " %s (%s)" % (frame
["name"], frame
["location"])
90 if __name__
== '__main__':