OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2008 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 Full execution command-line provided by subclassers via proc.""" | 141 Full execution command-line provided by subclassers via proc.""" |
142 logging.info("starting execution...") | 142 logging.info("starting execution...") |
143 | 143 |
144 proc = self.ToolCommand() | 144 proc = self.ToolCommand() |
145 | 145 |
146 add_env = { | 146 add_env = { |
147 "G_SLICE" : "always-malloc", | 147 "G_SLICE" : "always-malloc", |
148 "NSS_DISABLE_ARENA_FREE_LIST" : "1", | 148 "NSS_DISABLE_ARENA_FREE_LIST" : "1", |
149 "GTEST_DEATH_TEST_USE_FORK" : "1", | 149 "GTEST_DEATH_TEST_USE_FORK" : "1", |
150 } | 150 } |
151 if common.IsWine(): | |
152 # TODO(timurrrr): Maybe we need it for TSan/Win too? | |
153 add_env["CHROME_ALLOCATOR"] = "winheap" | |
154 | |
155 for k,v in add_env.iteritems(): | 151 for k,v in add_env.iteritems(): |
156 logging.info("export %s=%s", k, v) | 152 logging.info("export %s=%s", k, v) |
157 os.putenv(k, v) | 153 os.putenv(k, v) |
158 | 154 |
159 return common.RunSubprocess(proc, self._timeout) | 155 return common.RunSubprocess(proc, self._timeout) |
160 | 156 |
161 def RunTestsAndAnalyze(self, check_sanity): | 157 def RunTestsAndAnalyze(self, check_sanity): |
162 exec_retcode = self.Execute() | 158 exec_retcode = self.Execute() |
163 analyze_retcode = self.Analyze(check_sanity) | 159 analyze_retcode = self.Analyze(check_sanity) |
164 | 160 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 parser.add_option("", "--num-callers", | 241 parser.add_option("", "--num-callers", |
246 dest="num_callers", default=30, | 242 dest="num_callers", default=30, |
247 help="number of callers to show in stack traces") | 243 help="number of callers to show in stack traces") |
248 parser.add_option("", "--generate_dsym", action="store_true", | 244 parser.add_option("", "--generate_dsym", action="store_true", |
249 default=False, | 245 default=False, |
250 help="Generate .dSYM file on Mac if needed. Slow!") | 246 help="Generate .dSYM file on Mac if needed. Slow!") |
251 | 247 |
252 def Setup(self, args): | 248 def Setup(self, args): |
253 if not BaseTool.Setup(self, args): | 249 if not BaseTool.Setup(self, args): |
254 return False | 250 return False |
255 if common.IsWine(): | 251 if common.IsMac(): |
256 self.PrepareForTestWine() | |
257 elif common.IsMac(): | |
258 self.PrepareForTestMac() | 252 self.PrepareForTestMac() |
259 return True | 253 return True |
260 | 254 |
261 def PrepareForTestMac(self): | 255 def PrepareForTestMac(self): |
262 """Runs dsymutil if needed. | 256 """Runs dsymutil if needed. |
263 | 257 |
264 Valgrind for Mac OS X requires that debugging information be in a .dSYM | 258 Valgrind for Mac OS X requires that debugging information be in a .dSYM |
265 bundle generated by dsymutil. It is not currently able to chase DWARF | 259 bundle generated by dsymutil. It is not currently able to chase DWARF |
266 data into .o files like gdb does, so executables without .dSYM bundles or | 260 data into .o files like gdb does, so executables without .dSYM bundles or |
267 with the Chromium-specific "fake_dsym" bundles generated by | 261 with the Chromium-specific "fake_dsym" bundles generated by |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 # until the end, and is then killed, which is silly. | 308 # until the end, and is then killed, which is silly. |
315 common.RunSubprocess(dsymutil_command) | 309 common.RunSubprocess(dsymutil_command) |
316 | 310 |
317 if saved_test_command: | 311 if saved_test_command: |
318 os.rename(saved_test_command, test_command) | 312 os.rename(saved_test_command, test_command) |
319 else: | 313 else: |
320 logging.info("No real .dSYM for test_command. Line numbers will " | 314 logging.info("No real .dSYM for test_command. Line numbers will " |
321 "not be shown. Either tell xcode to generate .dSYM " | 315 "not be shown. Either tell xcode to generate .dSYM " |
322 "file, or use --generate_dsym option to this tool.") | 316 "file, or use --generate_dsym option to this tool.") |
323 | 317 |
324 def PrepareForTestWine(self): | |
325 """Set up the Wine environment. | |
326 | |
327 We need to run some sanity checks, set up a Wine prefix, and make sure | |
328 wineserver is running by starting a dummy win32 program. | |
329 """ | |
330 if not os.path.exists('/usr/share/ca-certificates/root_ca_cert.crt'): | |
331 logging.warning('WARNING: SSL certificate missing! SSL tests will fail.') | |
332 logging.warning('You need to run:') | |
333 logging.warning('sudo cp src/net/data/ssl/certificates/root_ca_cert.crt ' | |
334 '/usr/share/ca-certificates/') | |
335 logging.warning('sudo vi /etc/ca-certificates.conf') | |
336 logging.warning(' (and add the line root_ca_cert.crt)') | |
337 logging.warning('sudo update-ca-certificates') | |
338 | |
339 # Shutdown the Wine server in case the last run got interrupted. | |
340 common.RunSubprocess([os.environ.get('WINESERVER'), '-k']) | |
341 | |
342 # Yes, this can be dangerous if $WINEPREFIX is set incorrectly. | |
343 shutil.rmtree(os.environ.get('WINEPREFIX'), ignore_errors=True) | |
344 | |
345 winetricks = os.path.join(self._source_dir, 'tools', 'valgrind', | |
346 'wine_memcheck', 'winetricks') | |
347 common.RunSubprocess(['sh', winetricks, | |
348 'nocrashdialog', 'corefonts', 'gecko']) | |
349 time.sleep(1) | |
350 | |
351 # Start a dummy program like winemine so Valgrind won't run memcheck on | |
352 # the wineserver startup routine when it launches the test binary, which | |
353 # is slow and not interesting to us. | |
354 common.RunSubprocessInBackground([os.environ.get('WINE'), 'winemine']) | |
355 return | |
356 | |
357 def ToolCommand(self): | 318 def ToolCommand(self): |
358 """Get the valgrind command to run.""" | 319 """Get the valgrind command to run.""" |
359 # Note that self._args begins with the exe to be run. | 320 # Note that self._args begins with the exe to be run. |
360 tool_name = self.ToolName() | 321 tool_name = self.ToolName() |
361 | 322 |
362 # Construct the valgrind command. | 323 # Construct the valgrind command. |
363 if self.SelfContained(): | 324 if self.SelfContained(): |
364 proc = ["valgrind-%s.sh" % tool_name] | 325 proc = ["valgrind-%s.sh" % tool_name] |
365 else: | 326 else: |
366 proc = ["valgrind", "--tool=%s" % tool_name] | 327 proc = ["valgrind", "--tool=%s" % tool_name] |
(...skipping 26 matching lines...) Expand all Loading... |
393 if self._options.indirect: | 354 if self._options.indirect: |
394 self.CreateBrowserWrapper(" ".join(proc), logfilename) | 355 self.CreateBrowserWrapper(" ".join(proc), logfilename) |
395 proc = [] | 356 proc = [] |
396 proc += self._args | 357 proc += self._args |
397 return proc | 358 return proc |
398 | 359 |
399 def ToolSpecificFlags(self): | 360 def ToolSpecificFlags(self): |
400 raise NotImplementedError, "This method should be implemented " \ | 361 raise NotImplementedError, "This method should be implemented " \ |
401 "in the tool-specific subclass" | 362 "in the tool-specific subclass" |
402 | 363 |
403 def Cleanup(self): | |
404 if common.IsWine(): | |
405 # Shutdown the Wine server. | |
406 common.RunSubprocess([os.environ.get('WINESERVER'), '-k']) | |
407 | |
408 def CreateBrowserWrapper(self, command, logfiles): | 364 def CreateBrowserWrapper(self, command, logfiles): |
409 """The program being run invokes Python or something else | 365 """The program being run invokes Python or something else |
410 that can't stand to be valgrinded, and also invokes | 366 that can't stand to be valgrinded, and also invokes |
411 the Chrome browser. Set an environment variable to | 367 the Chrome browser. Set an environment variable to |
412 tell the program to prefix the Chrome commandline | 368 tell the program to prefix the Chrome commandline |
413 with a magic wrapper. Build the magic wrapper here. | 369 with a magic wrapper. Build the magic wrapper here. |
414 """ | 370 """ |
415 (fd, indirect_fname) = tempfile.mkstemp(dir=self.temp_dir, | 371 (fd, indirect_fname) = tempfile.mkstemp(dir=self.temp_dir, |
416 prefix="browser_wrapper.", | 372 prefix="browser_wrapper.", |
417 text=True) | 373 text=True) |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 logging.info("Please see " + self.MORE_INFO_URL + " for more information " + | 855 logging.info("Please see " + self.MORE_INFO_URL + " for more information " + |
900 "on RaceVerifier") | 856 "on RaceVerifier") |
901 return ret | 857 return ret |
902 | 858 |
903 def Run(self, args, module): | 859 def Run(self, args, module): |
904 return self.Main(args, False) | 860 return self.Main(args, False) |
905 | 861 |
906 | 862 |
907 class ToolFactory: | 863 class ToolFactory: |
908 def Create(self, tool_name): | 864 def Create(self, tool_name): |
909 if tool_name == "memcheck" and not common.IsWine(): | 865 if tool_name == "memcheck": |
910 return Memcheck() | |
911 if tool_name == "wine_memcheck" and common.IsWine(): | |
912 return Memcheck() | 866 return Memcheck() |
913 if tool_name == "tsan": | 867 if tool_name == "tsan": |
914 if common.IsWindows(): | 868 if common.IsWindows(): |
915 return ThreadSanitizerWindows() | 869 return ThreadSanitizerWindows() |
916 else: | 870 else: |
917 return ThreadSanitizerPosix() | 871 return ThreadSanitizerPosix() |
918 if tool_name == "drmemory": | 872 if tool_name == "drmemory": |
919 return DrMemory() | 873 return DrMemory() |
920 if tool_name == "tsan_rv": | 874 if tool_name == "tsan_rv": |
921 return RaceVerifier() | 875 return RaceVerifier() |
922 try: | 876 try: |
923 platform_name = common.PlatformNames()[0] | 877 platform_name = common.PlatformNames()[0] |
924 except common.NotImplementedError: | 878 except common.NotImplementedError: |
925 platform_name = sys.platform + "(Unknown)" | 879 platform_name = sys.platform + "(Unknown)" |
926 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, | 880 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, |
927 platform_name) | 881 platform_name) |
928 | 882 |
929 def CreateTool(tool): | 883 def CreateTool(tool): |
930 return ToolFactory().Create(tool) | 884 return ToolFactory().Create(tool) |
931 | 885 |
932 if __name__ == '__main__': | 886 if __name__ == '__main__': |
933 logging.error(sys.argv[0] + " can not be run from command line") | 887 logging.error(sys.argv[0] + " can not be run from command line") |
934 sys.exit(1) | 888 sys.exit(1) |
OLD | NEW |