OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # drmemory_analyze.py | 6 # drmemory_analyze.py |
7 | 7 |
8 ''' Given a Dr. Memory output file, parses errors and uniques them.''' | 8 ''' Given a Dr. Memory output file, parses errors and uniques them.''' |
9 | 9 |
10 from collections import defaultdict | 10 from collections import defaultdict |
(...skipping 18 matching lines...) Expand all Loading... |
29 # make sense in a multiprocess report. | 29 # make sense in a multiprocess report. |
30 supp_lines = suppression.split("\n") | 30 supp_lines = suppression.split("\n") |
31 for l in xrange(len(supp_lines)): | 31 for l in xrange(len(supp_lines)): |
32 if supp_lines[l].startswith("name="): | 32 if supp_lines[l].startswith("name="): |
33 supp_lines[l] = "name=<insert_a_suppression_name_here>" | 33 supp_lines[l] = "name=<insert_a_suppression_name_here>" |
34 if supp_lines[l].startswith("chrome.dll!"): | 34 if supp_lines[l].startswith("chrome.dll!"): |
35 supp_lines[l] = supp_lines[l].replace("chrome.dll!", "*!") | 35 supp_lines[l] = supp_lines[l].replace("chrome.dll!", "*!") |
36 bang_index = supp_lines[l].find("!") | 36 bang_index = supp_lines[l].find("!") |
37 d_exe_index = supp_lines[l].find(".exe!") | 37 d_exe_index = supp_lines[l].find(".exe!") |
38 if bang_index >= 4 and d_exe_index + 4 == bang_index: | 38 if bang_index >= 4 and d_exe_index + 4 == bang_index: |
39 supp_lines[l] = "*.exe" + supp_lines[l][bang_index:] | 39 supp_lines[l] = "*" + supp_lines[l][bang_index:] |
40 self._suppression = "\n".join(supp_lines) | 40 self._suppression = "\n".join(supp_lines) |
41 | 41 |
42 def __str__(self): | 42 def __str__(self): |
43 output = self._report + "\n" | 43 output = self._report + "\n" |
44 if self._testcase: | 44 if self._testcase: |
45 output += "The report came from the `%s` test.\n" % self._testcase | 45 output += "The report came from the `%s` test.\n" % self._testcase |
46 output += "Suppression (error hash=#%016X#):\n" % self.ErrorHash() | 46 output += "Suppression (error hash=#%016X#):\n" % self.ErrorHash() |
47 output += "{\n%s\n}\n" % self._suppression | 47 output += "{\n%s\n}\n" % self._suppression |
48 | 48 |
49 # TODO(timurrrr): docs on suppressing? | 49 # TODO(timurrrr): docs on suppressing? |
50 #output += (" For more info on using suppressions see " | 50 #output += (" For more info on using suppressions see " |
51 # "http://dev.chromium.org/developers/how-tos/using-valgrind#TOC-S
uppressing-Errors") | 51 # "http://dev.chromium.org/developers/how-tos/using-valgrind#TOC-S
uppressing-Errors") |
52 return output | 52 return output |
53 | 53 |
54 # This is a device-independent hash identifying the suppression. | 54 # This is a device-independent hash identifying the suppression. |
55 # By printing out this hash we can find duplicate reports between tests and | 55 # By printing out this hash we can find duplicate reports between tests and |
56 # different shards running on multiple buildbots | 56 # different shards running on multiple buildbots |
57 def ErrorHash(self): | 57 def ErrorHash(self): |
58 return int(hashlib.md5(self._suppression).hexdigest()[:16], 16) | 58 return int(hashlib.md5(self._suppression).hexdigest()[:16], 16) |
59 | 59 |
60 def __hash__(self): | 60 def __hash__(self): |
61 return hash(self._suppression) | 61 return hash(self._suppression) |
62 | 62 |
| 63 def __eq__(self, rhs): |
| 64 return self._suppression == rhs |
| 65 |
63 | 66 |
64 class DrMemoryAnalyzer: | 67 class DrMemoryAnalyzer: |
65 ''' Given a set of Dr.Memory output files, parse all the errors out of | 68 ''' Given a set of Dr.Memory output files, parse all the errors out of |
66 them, unique them and output the results.''' | 69 them, unique them and output the results.''' |
67 | 70 |
68 def __init__(self): | 71 def __init__(self): |
69 self.known_errors = set() | 72 self.known_errors = set() |
70 self.error_count = 0; | 73 self.error_count = 0; |
71 | 74 |
72 def ReadLine(self): | 75 def ReadLine(self): |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 parser = optparse.OptionParser("usage: %prog [options] <files to analyze>") | 175 parser = optparse.OptionParser("usage: %prog [options] <files to analyze>") |
173 parser.add_option("", "--source_dir", | 176 parser.add_option("", "--source_dir", |
174 help="path to top of source tree for this build" | 177 help="path to top of source tree for this build" |
175 "(used to normalize source paths in baseline)") | 178 "(used to normalize source paths in baseline)") |
176 | 179 |
177 (options, args) = parser.parse_args() | 180 (options, args) = parser.parse_args() |
178 if len(args) == 0: | 181 if len(args) == 0: |
179 parser.error("no filename specified") | 182 parser.error("no filename specified") |
180 filenames = args | 183 filenames = args |
181 | 184 |
| 185 logging.getLogger().setLevel(logging.INFO) |
182 return DrMemoryAnalyzer().Report(filenames, None, False) | 186 return DrMemoryAnalyzer().Report(filenames, None, False) |
183 | 187 |
184 | 188 |
185 if __name__ == '__main__': | 189 if __name__ == '__main__': |
186 sys.exit(main()) | 190 sys.exit(main()) |
OLD | NEW |