Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: tools/android/memdump/memsymbols.py

Issue 19466005: Adding extended report to memdump with resident pages bit reporting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file
6
7 import base64
8 import os
9 import sys
10 import re
11
12 from optparse import OptionParser
13
14 """ Extracts the list of resident symbols of a library loaded in a process.
bulach 2013/07/22 12:59:39 nit: remove space before Extracts
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
15
16 This scripts combines the extended output of memdump for a given process
17 (obtained through memdump -x PID) and the symbol table of a .so loaded in that
18 process (obtained through nm -C lib-with-symbols.so), filtering out only those
19 symbols that, at the time of the snapshot, were resident in memory (that are,
20 the symbols which start address belongs to a mapped page of the .so which was
21 resident at the time of the snapshot).
22 The aim is to perform a "code coverage"-like profiling of a binary, intersecting
23 run-time information (list of resident pages) and debug symbols.
24 """
25
26 PAGE_SIZE = 4096
bulach 2013/07/22 12:59:39 nit: _ prefix. also, below should be _TestBit and
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
27
28 def test_bit(word, bit):
29 assert(bit >= 0 and bit < 8)
30 return not not ((word >> bit) & 1)
31
32 def hex_addr(addr):
33 return hex(addr)[2:].zfill(8)
34
35 def main(argv):
36 MAP_RX = re.compile(
37 r'^([0-9a-f]+)-([0-9a-f]+) ([\w-]+) ([0-9a-f]+) .* "(.*)" \[(.*)\]$')
38 NM_RX = re.compile(r'^([0-9a-f]+)\s+\w+\s+.*$')
39
40 parser = OptionParser()
41 parser.add_option("-r", "--reverse",
42 action="store_true", dest="reverse", default=False,
43 help="Print out non present symbols")
44 parser.add_option("-v", "--verbose",
45 action="store_true", dest="verbose", default=False,
46 help="Print out verbose debug information.")
47
48 (options, args) = parser.parse_args()
49
50 if len(args) != 3:
51 print 'Usage: %s [-v] memdump.file nm.file library.so' % (
52 os.path.basename(argv[0]))
53 return 1
54
bulach 2013/07/22 12:59:39 it'd be nicer to split 54-134 into its own functio
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
55 memdump_file = args[0]
56 nm_file = args[1]
57 lib_name = args[2]
58 resident_pages = set()
59
60 # First process the memdump output and extract the mappings which match the
61 # given library name.
62 memdump_fh = open(memdump_file, 'r')
Philippe 2013/07/22 09:20:55 Nit: will this work with stdin?
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Added special '-' handling to read memdump from st
pliard 2013/07/23 09:08:22 Nice, thanks.
63 for line in memdump_fh:
64 line = line.rstrip('\r\n')
65 if line.startswith('[ PID'):
66 continue
67
68 r = MAP_RX.match(line)
69 if not r:
70 sys.stderr.write('Skipping %s from %s\n' % (line, nm_file))
71 continue
72
73 map_start = int(r.group(1), 16)
74 map_end = int(r.group(2), 16)
75 prot = r.group(3)
76 offset = int(r.group(4), 16)
77 assert(offset % PAGE_SIZE == 0)
78 lib = r.group(5)
79 enc_bitmap = r.group(6)
80
81 #if prot == 'r-xp':
Philippe 2013/07/22 09:20:55 Nit: should we keep this? :)
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
82 # continue
83 if not lib.endswith(lib_name):
84 continue
85
86 bitmap = base64.b64decode(enc_bitmap)
87 map_pages_count = (map_end - map_start + 1) / PAGE_SIZE
88 bitmap_pages_count = len(bitmap) * 8
89
90 if options.verbose:
91 print 'Found %s: mapped %d pages in mode %s @ offset %s.' % (
92 lib, map_pages_count, prot, hex_addr(offset))
93 print ' Map range in the process VA: [%s - %s]. Len: %s' % (
94 hex_addr(map_start),
95 hex_addr(map_end),
96 hex_addr(map_pages_count * PAGE_SIZE))
97 print ' Corresponding addresses in the binary: [%s - %s]. Len: %s' % (
98 hex_addr(offset),
99 hex_addr(offset + map_end - map_start),
100 hex_addr(map_pages_count * PAGE_SIZE))
101 print ' Bitmap: %d pages' % bitmap_pages_count
102 print ''
103
104 assert(bitmap_pages_count >= map_pages_count)
105 for i in xrange(map_pages_count):
106 bitmap_idx = i / 8
107 bitmap_off = i % 8
108 if (bitmap_idx < len(bitmap) and
109 test_bit(ord(bitmap[bitmap_idx]), bitmap_off)):
110 resident_pages.add(offset/PAGE_SIZE + i)
Philippe 2013/07/22 09:20:55 Nit: spaces around binary operators (also on line
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
111
112 # Now process the nm symbol table, filtering out the resident symbols.
113 nm_fh = open(nm_file, 'r')
114 last_sym_matched = False
115 for line in nm_fh:
116 line = line.rstrip('\r\n')
117 if line.startswith(' '):
118 if last_sym_matched:
119 print line
120 continue
121
122 r = NM_RX.match(line)
123 if not r:
124 sys.stderr.write('Skipping %s from %s\n' % (line, nm_file))
125 continue
126
127 sym_addr = int(r.group(1),16)
128 sym_page = sym_addr / PAGE_SIZE
129 last_sym_matched = (sym_page in resident_pages)
130 if options.reverse:
131 last_sym_matched = not last_sym_matched
132 if last_sym_matched:
133 print line
134
135 if __name__=='__main__':
136 main(sys.argv)
bulach 2013/07/22 12:59:39 nit: return main(sys.argv)
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 You mean sys.exit, right?
bulach 2013/07/23 08:10:57 yep, thanks!
OLDNEW
« tools/android/memdump/memdump.cc ('K') | « tools/android/memdump/memdump.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698