Chromium Code Reviews| Index: tools/drmemory/scripts/valgrind_test.py |
| diff --git a/tools/drmemory/scripts/valgrind_test.py b/tools/drmemory/scripts/valgrind_test.py |
| index bde300241cc34b7b9ab4a31f3f17089e2c2123c6..2b45cd9f1976a77dbe8a1553419e8f0574a94e4b 100644 |
| --- a/tools/drmemory/scripts/valgrind_test.py |
| +++ b/tools/drmemory/scripts/valgrind_test.py |
| @@ -230,277 +230,6 @@ class BaseTool(object): |
| return self.Main(args, check_sanity, min_runtime_in_seconds) |
| -class ValgrindTool(BaseTool): |
| - """Abstract class for running Valgrind tools. |
| - |
| - Always subclass this and implement ToolSpecificFlags() and |
| - ExtendOptionParser() for tool-specific stuff. |
| - """ |
| - def __init__(self): |
| - super(ValgrindTool, self).__init__() |
| - self.RegisterOptionParserHook(ValgrindTool.ExtendOptionParser) |
| - |
| - def UseXML(self): |
| - # Override if tool prefers nonxml output |
| - return True |
| - |
| - def ExtendOptionParser(self, parser): |
| - parser.add_option("", "--suppressions", default=[], |
| - action="append", |
| - help="path to a valgrind suppression file") |
| - parser.add_option("", "--indirect", action="store_true", |
| - default=False, |
| - help="set BROWSER_WRAPPER rather than " |
| - "running valgrind directly") |
| - parser.add_option("", "--indirect_webkit_layout", action="store_true", |
| - default=False, |
| - help="set --wrapper rather than running Dr. Memory " |
| - "directly.") |
| - parser.add_option("", "--trace_children", action="store_true", |
| - default=False, |
| - help="also trace child processes") |
| - parser.add_option("", "--num-callers", |
| - dest="num_callers", default=30, |
| - help="number of callers to show in stack traces") |
| - parser.add_option("", "--generate_dsym", action="store_true", |
| - default=False, |
| - help="Generate .dSYM file on Mac if needed. Slow!") |
| - |
| - def Setup(self, args): |
| - if not BaseTool.Setup(self, args): |
| - return False |
| - if common.IsMac(): |
| - self.PrepareForTestMac() |
| - return True |
| - |
| - def PrepareForTestMac(self): |
| - """Runs dsymutil if needed. |
| - |
| - Valgrind for Mac OS X requires that debugging information be in a .dSYM |
| - bundle generated by dsymutil. It is not currently able to chase DWARF |
| - data into .o files like gdb does, so executables without .dSYM bundles or |
| - with the Chromium-specific "fake_dsym" bundles generated by |
| - build/mac/strip_save_dsym won't give source file and line number |
| - information in valgrind. |
| - |
| - This function will run dsymutil if the .dSYM bundle is missing or if |
| - it looks like a fake_dsym. A non-fake dsym that already exists is assumed |
| - to be up-to-date. |
| - """ |
| - test_command = self._args[0] |
| - dsym_bundle = self._args[0] + '.dSYM' |
| - dsym_file = os.path.join(dsym_bundle, 'Contents', 'Resources', 'DWARF', |
| - os.path.basename(test_command)) |
| - dsym_info_plist = os.path.join(dsym_bundle, 'Contents', 'Info.plist') |
| - |
| - needs_dsymutil = True |
| - saved_test_command = None |
| - |
| - if os.path.exists(dsym_file) and os.path.exists(dsym_info_plist): |
| - # Look for the special fake_dsym tag in dsym_info_plist. |
| - dsym_info_plist_contents = open(dsym_info_plist).read() |
| - |
| - if not re.search('^\s*<key>fake_dsym</key>$', dsym_info_plist_contents, |
| - re.MULTILINE): |
| - # fake_dsym is not set, this is a real .dSYM bundle produced by |
| - # dsymutil. dsymutil does not need to be run again. |
| - needs_dsymutil = False |
| - else: |
| - # fake_dsym is set. dsym_file is a copy of the original test_command |
| - # before it was stripped. Copy it back to test_command so that |
| - # dsymutil has unstripped input to work with. Move the stripped |
| - # test_command out of the way, it will be restored when this is |
| - # done. |
| - saved_test_command = test_command + '.stripped' |
| - os.rename(test_command, saved_test_command) |
| - shutil.copyfile(dsym_file, test_command) |
| - shutil.copymode(saved_test_command, test_command) |
| - |
| - if needs_dsymutil: |
| - if self._options.generate_dsym: |
| - # Remove the .dSYM bundle if it exists. |
| - shutil.rmtree(dsym_bundle, True) |
| - |
| - dsymutil_command = ['dsymutil', test_command] |
| - |
| - # dsymutil is crazy slow. Ideally we'd have a timeout here, |
| - # but common.RunSubprocess' timeout is only checked |
| - # after each line of output; dsymutil is silent |
| - # until the end, and is then killed, which is silly. |
| - common.RunSubprocess(dsymutil_command) |
| - |
| - if saved_test_command: |
| - os.rename(saved_test_command, test_command) |
| - else: |
| - logging.info("No real .dSYM for test_command. Line numbers will " |
| - "not be shown. Either tell xcode to generate .dSYM " |
| - "file, or use --generate_dsym option to this tool.") |
| - |
| - def ToolCommand(self): |
| - """Get the valgrind command to run.""" |
| - # Note that self._args begins with the exe to be run. |
| - tool_name = self.ToolName() |
| - |
| - # Construct the valgrind command. |
| - if 'CHROME_VALGRIND' in os.environ: |
| - path = os.path.join(os.environ['CHROME_VALGRIND'], "bin", "valgrind") |
| - else: |
| - path = "valgrind" |
| - proc = [path, "--tool=%s" % tool_name] |
| - |
| - proc += ["--num-callers=%i" % int(self._options.num_callers)] |
| - |
| - if self._options.trace_children: |
| - proc += ["--trace-children=yes"] |
| - proc += ["--trace-children-skip='*dbus-daemon*'"] |
| - proc += ["--trace-children-skip='*dbus-launch*'"] |
| - proc += ["--trace-children-skip='*perl*'"] |
| - proc += ["--trace-children-skip='*python*'"] |
| - # This is really Python, but for some reason Valgrind follows it. |
| - proc += ["--trace-children-skip='*lsb_release*'"] |
| - |
| - proc += self.ToolSpecificFlags() |
| - proc += self._tool_flags |
| - |
| - suppression_count = 0 |
| - for suppression_file in self._options.suppressions: |
| - if os.path.exists(suppression_file): |
| - suppression_count += 1 |
| - proc += ["--suppressions=%s" % suppression_file] |
| - |
| - if not suppression_count: |
| - logging.warning("WARNING: NOT USING SUPPRESSIONS!") |
| - |
| - logfilename = self.log_dir + ("/%s." % tool_name) + "%p" |
| - if self.UseXML(): |
| - proc += ["--xml=yes", "--xml-file=" + logfilename] |
| - else: |
| - proc += ["--log-file=" + logfilename] |
| - |
| - # The Valgrind command is constructed. |
| - |
| - # Handle --indirect_webkit_layout separately. |
| - if self._options.indirect_webkit_layout: |
| - # Need to create the wrapper before modifying |proc|. |
| - wrapper = self.CreateBrowserWrapper(proc, webkit=True) |
| - proc = self._args |
| - proc.append("--wrapper") |
| - proc.append(wrapper) |
| - return proc |
| - |
| - if self._options.indirect: |
| - wrapper = self.CreateBrowserWrapper(proc) |
| - os.environ["BROWSER_WRAPPER"] = wrapper |
| - logging.info('export BROWSER_WRAPPER=' + wrapper) |
| - proc = [] |
| - proc += self._args |
| - return proc |
| - |
| - def ToolSpecificFlags(self): |
| - raise NotImplementedError, "This method should be implemented " \ |
| - "in the tool-specific subclass" |
| - |
| - def CreateBrowserWrapper(self, proc, webkit=False): |
| - """The program being run invokes Python or something else that can't stand |
| - to be valgrinded, and also invokes the Chrome browser. In this case, use a |
| - magic wrapper to only valgrind the Chrome browser. Build the wrapper here. |
| - Returns the path to the wrapper. It's up to the caller to use the wrapper |
| - appropriately. |
| - """ |
| - command = " ".join(proc) |
| - # Add the PID of the browser wrapper to the logfile names so we can |
| - # separate log files for different UI tests at the analyze stage. |
| - command = command.replace("%p", "$$.%p") |
| - |
| - (fd, indirect_fname) = tempfile.mkstemp(dir=self.log_dir, |
| - prefix="browser_wrapper.", |
| - text=True) |
| - f = os.fdopen(fd, "w") |
| - f.write('#!/bin/bash\n' |
| - 'echo "Started Valgrind wrapper for this test, PID=$$" >&2\n') |
| - |
| - f.write('DIR=`dirname $0`\n' |
| - 'TESTNAME_FILE=$DIR/testcase.$$.name\n\n') |
| - |
| - if webkit: |
| - # Webkit layout_tests pass the URL as the first line of stdin. |
| - f.write('tee $TESTNAME_FILE | %s "$@"\n' % command) |
| - else: |
| - # Try to get the test case name by looking at the program arguments. |
| - # i.e. Chromium ui_tests used --test-name arg. |
| - # TODO(timurrrr): This doesn't handle "--test-name Test.Name" |
| - # TODO(timurrrr): ui_tests are dead. Where do we use the non-webkit |
| - # wrapper now? browser_tests? What do they do? |
| - f.write('for arg in $@\ndo\n' |
| - ' if [[ "$arg" =~ --test-name=(.*) ]]\n then\n' |
| - ' echo ${BASH_REMATCH[1]} >$TESTNAME_FILE\n' |
| - ' fi\n' |
| - 'done\n\n' |
| - '%s "$@"\n' % command) |
| - |
| - f.close() |
| - os.chmod(indirect_fname, stat.S_IRUSR|stat.S_IXUSR) |
| - return indirect_fname |
| - |
| - def CreateAnalyzer(self): |
| - raise NotImplementedError, "This method should be implemented " \ |
| - "in the tool-specific subclass" |
| - |
| - def GetAnalyzeResults(self, check_sanity=False): |
| - # Glob all the files in the log directory |
| - filenames = glob.glob(self.log_dir + "/" + self.ToolName() + ".*") |
| - |
| - # If we have browser wrapper, the logfiles are named as |
| - # "toolname.wrapper_PID.valgrind_PID". |
| - # Let's extract the list of wrapper_PIDs and name it ppids |
| - ppids = set([int(f.split(".")[-2]) \ |
| - for f in filenames if re.search("\.[0-9]+\.[0-9]+$", f)]) |
| - |
| - analyzer = self.CreateAnalyzer() |
| - if len(ppids) == 0: |
| - # Fast path - no browser wrapper was set. |
| - return analyzer.Report(filenames, None, check_sanity) |
| - |
| - ret = 0 |
| - for ppid in ppids: |
| - testcase_name = None |
| - try: |
| - f = open(self.log_dir + ("/testcase.%d.name" % ppid)) |
| - testcase_name = f.read().strip() |
| - f.close() |
| - wk_layout_prefix="third_party/WebKit/LayoutTests/" |
| - wk_prefix_at = testcase_name.rfind(wk_layout_prefix) |
| - if wk_prefix_at != -1: |
| - testcase_name = testcase_name[wk_prefix_at + len(wk_layout_prefix):] |
| - except IOError: |
| - pass |
| - print "=====================================================" |
| - print " Below is the report for valgrind wrapper PID=%d." % ppid |
| - if testcase_name: |
| - print " It was used while running the `%s` test." % testcase_name |
| - else: |
| - print " You can find the corresponding test" |
| - print " by searching the above log for 'PID=%d'" % ppid |
| - sys.stdout.flush() |
| - |
| - ppid_filenames = [f for f in filenames \ |
| - if re.search("\.%d\.[0-9]+$" % ppid, f)] |
| - # check_sanity won't work with browser wrappers |
| - assert check_sanity == False |
| - ret |= analyzer.Report(ppid_filenames, testcase_name) |
| - print "=====================================================" |
| - sys.stdout.flush() |
| - |
| - if ret != 0: |
| - print "" |
| - print "The Valgrind reports are grouped by test names." |
| - print "Each test has its PID printed in the log when the test was run" |
| - print "and at the beginning of its Valgrind report." |
| - print "Hint: you can search for the reports by Ctrl+F -> `=#`" |
| - sys.stdout.flush() |
| - |
| - return ret |
| - |
| class DrMemory(BaseTool): |
| """Dr.Memory |
| Dynamic memory error detector for Windows. |
| @@ -527,11 +256,7 @@ class DrMemory(BaseTool): |
| help="Monitor python child processes. If off, neither " |
| "python children nor any children of python children " |
| "will be monitored.") |
| - parser.add_option("", "--indirect", action="store_true", |
| - default=False, |
| - help="set BROWSER_WRAPPER rather than " |
| - "running Dr. Memory directly on the harness") |
| - parser.add_option("", "--indirect_webkit_layout", action="store_true", |
| + parser.add_option("", "--indirect_pdfium_test", action="store_true", |
| default=False, |
| help="set --wrapper rather than running valgrind " |
|
Lei Zhang
2015/11/20 00:17:47
s/valgrind/Dr Memory/ ?
zhaoqin1
2015/11/21 04:20:46
Done.
|
| "directly.") |
| @@ -677,20 +402,12 @@ class DrMemory(BaseTool): |
| # Dr.Memory requires -- to separate tool flags from the executable name. |
| proc += ["--"] |
| - if self._options.indirect or self._options.indirect_webkit_layout: |
| - wrapper_path = os.path.join(self._source_dir, |
| - "tools", "valgrind", "browser_wrapper_win.py") |
| - wrapper = " ".join(["python", wrapper_path] + proc) |
| - self.CreateBrowserWrapper(wrapper) |
| - logging.info("browser wrapper = " + " ".join(proc)) |
| - if self._options.indirect_webkit_layout: |
| - proc = self._args |
| - # Layout tests want forward slashes. |
| - wrapper = wrapper.replace('\\', '/') |
| - proc += ["--wrapper", wrapper] |
| - return proc |
| - else: |
| - proc = [] |
| + if self._options.indirect_pdfium_test: |
| + logging.info("pdfium wrapper = " + " ".join(proc)) |
|
Lei Zhang
2015/11/20 00:17:47
Save the '" ".join(proc)' result and use it on the
zhaoqin1
2015/11/21 04:20:46
Done.
|
| + wrapper = " ".join(proc) |
| + proc = self._args |
| + proc += ["--wrapper", wrapper] |
| + return proc |
| # Note that self._args begins with the name of the exe to be run. |
| self._args[0] = common.NormalizeWindowsPath(self._args[0]) |
| @@ -708,7 +425,7 @@ class DrMemory(BaseTool): |
| analyzer = drmemory_analyze.DrMemoryAnalyzer() |
| ret = 0 |
| - if not self._options.indirect and not self._options.indirect_webkit_layout: |
| + if not self._options.indirect_pdfium_test: |
| filenames = glob.glob(self.log_dir + "/*/results.txt") |
| ret = analyzer.Report(filenames, None, check_sanity) |