| 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 |