| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/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 # valgrind_test.py | 6 # valgrind_test.py |
| 7 | 7 |
| 8 """Runs an exe through Valgrind and puts the intermediate files in a | 8 """Runs an exe through Valgrind and puts the intermediate files in a |
| 9 directory. | 9 directory. |
| 10 """ | 10 """ |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 | 429 |
| 430 f.close() | 430 f.close() |
| 431 os.chmod(indirect_fname, stat.S_IRUSR|stat.S_IXUSR) | 431 os.chmod(indirect_fname, stat.S_IRUSR|stat.S_IXUSR) |
| 432 return indirect_fname | 432 return indirect_fname |
| 433 | 433 |
| 434 def CreateAnalyzer(self): | 434 def CreateAnalyzer(self): |
| 435 raise NotImplementedError, "This method should be implemented " \ | 435 raise NotImplementedError, "This method should be implemented " \ |
| 436 "in the tool-specific subclass" | 436 "in the tool-specific subclass" |
| 437 | 437 |
| 438 def GetAnalyzeResults(self, check_sanity=False): | 438 def GetAnalyzeResults(self, check_sanity=False): |
| 439 # Glob all the files in the "testing.tmp" directory | 439 # Glob all the files in the log directory |
| 440 filenames = glob.glob(self.log_dir + "/" + self.ToolName() + ".*") | 440 filenames = glob.glob(self.log_dir + "/" + self.ToolName() + ".*") |
| 441 | 441 |
| 442 # If we have browser wrapper, the logfiles are named as | 442 # If we have browser wrapper, the logfiles are named as |
| 443 # "toolname.wrapper_PID.valgrind_PID". | 443 # "toolname.wrapper_PID.valgrind_PID". |
| 444 # Let's extract the list of wrapper_PIDs and name it ppids | 444 # Let's extract the list of wrapper_PIDs and name it ppids |
| 445 ppids = set([int(f.split(".")[-2]) \ | 445 ppids = set([int(f.split(".")[-2]) \ |
| 446 for f in filenames if re.search("\.[0-9]+\.[0-9]+$", f)]) | 446 for f in filenames if re.search("\.[0-9]+\.[0-9]+$", f)]) |
| 447 | 447 |
| 448 analyzer = self.CreateAnalyzer() | 448 analyzer = self.CreateAnalyzer() |
| 449 if len(ppids) == 0: | 449 if len(ppids) == 0: |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 | 872 |
| 873 if not self.handle_uninits_and_leaks: | 873 if not self.handle_uninits_and_leaks: |
| 874 proc += ["-no_check_uninitialized", "-no_count_leaks"] | 874 proc += ["-no_check_uninitialized", "-no_count_leaks"] |
| 875 | 875 |
| 876 proc += self._tool_flags | 876 proc += self._tool_flags |
| 877 | 877 |
| 878 # Dr.Memory requires -- to separate tool flags from the executable name. | 878 # Dr.Memory requires -- to separate tool flags from the executable name. |
| 879 proc += ["--"] | 879 proc += ["--"] |
| 880 | 880 |
| 881 if self._options.indirect: | 881 if self._options.indirect: |
| 882 self.CreateBrowserWrapper(" ".join(proc)) | 882 # TODO(timurrrr): reuse for TSan on Windows |
| 883 self.CreateBrowserWrapper(" ".join( |
| 884 ["python", "tools/valgrind/browser_wrapper_win.py"] + proc)) |
| 883 proc = [] | 885 proc = [] |
| 884 | 886 |
| 885 # Note that self._args begins with the name of the exe to be run. | 887 # Note that self._args begins with the name of the exe to be run. |
| 886 self._args[0] = common.NormalizeWindowsPath(self._args[0]) | 888 self._args[0] = common.NormalizeWindowsPath(self._args[0]) |
| 887 proc += self._args | 889 proc += self._args |
| 888 return proc | 890 return proc |
| 889 | 891 |
| 890 def CreateBrowserWrapper(self, command): | 892 def CreateBrowserWrapper(self, command): |
| 891 os.putenv("BROWSER_WRAPPER", command) | 893 os.putenv("BROWSER_WRAPPER", command) |
| 892 | 894 |
| 893 def Analyze(self, check_sanity=False): | 895 def Analyze(self, check_sanity=False): |
| 894 # Glob all the results files in the "testing.tmp" directory | 896 # Use one analyzer for all the log files to avoid printing duplicate reports |
| 895 filenames = glob.glob(self.log_dir + "/*/results.txt") | 897 # |
| 898 # TODO(timurrrr): unify this with Valgrind and other tools when we have |
| 899 # http://code.google.com/p/drmemory/issues/detail?id=684 |
| 900 analyzer = drmemory_analyze.DrMemoryAnalyzer() |
| 896 | 901 |
| 897 analyzer = drmemory_analyze.DrMemoryAnalyze(self._source_dir, filenames) | 902 ret = 0 |
| 898 ret = analyzer.Report(check_sanity) | 903 if not self._options.indirect: |
| 904 filenames = glob.glob(self.log_dir + "/*/results.txt") |
| 905 |
| 906 ret = analyzer.Report(filenames, None, check_sanity) |
| 907 else: |
| 908 testcases = glob.glob(self.log_dir + "/testcase.*.logs") |
| 909 # if we have browser wrapper, the per-test logdirs are named as |
| 910 # "testcase.wrapper_pid". |
| 911 # let's extract the list of wrapper_pids and name it ppids |
| 912 ppids = set([int(f.split(".")[-2]) for f in testcases]) |
| 913 |
| 914 for ppid in ppids: |
| 915 testcase_name = None |
| 916 try: |
| 917 f = open(self.log_dir + ("/testcase.%d.name" % ppid)) |
| 918 testcase_name = f.read().strip() |
| 919 f.close() |
| 920 except IOError: |
| 921 pass |
| 922 print "=====================================================" |
| 923 print " Below is the report for drmemory wrapper PID=%d." % ppid |
| 924 if testcase_name: |
| 925 print " It was used while running the `%s` test." % testcase_name |
| 926 else: |
| 927 # TODO(timurrrr): hm, the PID line is suppressed on Windows... |
| 928 print " You can find the corresponding test" |
| 929 print " by searching the above log for 'PID=%d'" % ppid |
| 930 sys.stdout.flush() |
| 931 ppid_filenames = glob.glob("%s/testcase.%d.logs/*/results.txt" % |
| 932 (self.log_dir, ppid)) |
| 933 ret |= analyzer.Report(ppid_filenames, testcase_name, False) |
| 934 print "=====================================================" |
| 935 sys.stdout.flush() |
| 936 |
| 937 logging.info("Please see http://dev.chromium.org/developers/how-tos/" |
| 938 "using-drmemory for the info on Dr. Memory") |
| 899 return ret | 939 return ret |
| 900 | 940 |
| 901 | 941 |
| 902 # RaceVerifier support. See | 942 # RaceVerifier support. See |
| 903 # http://code.google.com/p/data-race-test/wiki/RaceVerifier for more details. | 943 # http://code.google.com/p/data-race-test/wiki/RaceVerifier for more details. |
| 904 class ThreadSanitizerRV1Analyzer(tsan_analyze.TsanAnalyzer): | 944 class ThreadSanitizerRV1Analyzer(tsan_analyze.TsanAnalyzer): |
| 905 """ TsanAnalyzer that saves race reports to a file. """ | 945 """ TsanAnalyzer that saves race reports to a file. """ |
| 906 | 946 |
| 907 TMP_FILE = "rvlog.tmp" | 947 TMP_FILE = "rvlog.tmp" |
| 908 | 948 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 platform_name = sys.platform + "(Unknown)" | 1185 platform_name = sys.platform + "(Unknown)" |
| 1146 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, | 1186 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, |
| 1147 platform_name) | 1187 platform_name) |
| 1148 | 1188 |
| 1149 def CreateTool(tool): | 1189 def CreateTool(tool): |
| 1150 return ToolFactory().Create(tool) | 1190 return ToolFactory().Create(tool) |
| 1151 | 1191 |
| 1152 if __name__ == '__main__': | 1192 if __name__ == '__main__': |
| 1153 logging.error(sys.argv[0] + " can not be run from command line") | 1193 logging.error(sys.argv[0] + " can not be run from command line") |
| 1154 sys.exit(1) | 1194 sys.exit(1) |
| OLD | NEW |