Chromium Code Reviews| Index: tools/valgrind/valgrind_test.py |
| =================================================================== |
| --- tools/valgrind/valgrind_test.py (revision 12673) |
| +++ tools/valgrind/valgrind_test.py (working copy) |
| @@ -14,6 +14,7 @@ |
| import logging |
| import optparse |
| import os |
| +import re |
| import shutil |
| import stat |
| import sys |
| @@ -100,6 +101,10 @@ |
| def Setup(self): |
| return self.ParseArgv() |
| + def PrepareForTest(self): |
| + """Perform necessary tasks prior to executing the test.""" |
| + pass |
| + |
| def ValgrindCommand(self): |
| """Get the valgrind command to run.""" |
| raise RuntimeError, "Never use Valgrind directly. Always subclass and " \ |
| @@ -136,6 +141,8 @@ |
| return True |
| def RunTestsAndAnalyze(self): |
| + self.PrepareForTest() |
| + |
| self.Execute() |
| if self._generate_suppressions: |
| logging.info("Skipping analysis to let you look at the raw output...") |
| @@ -240,6 +247,62 @@ |
| def __init__(self): |
| Valgrind.__init__(self) |
| + def PrepareForTest(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) |
| + |
| + if needs_dsymutil: |
| + # Remove the .dSYM bundle if it exists. |
| + shutil.rmtree(dsym_bundle, True) |
| + |
| + dsymutil_command = ['dsymutil', test_command] |
| + |
| + # dsymutil is crazy slow. Let it run for up to a half hour. I hope |
| + # that's enough. |
| + common.RunSubprocess(dsymutil_command, 30 * 60) |
| + |
| + if saved_test_command: |
| + os.rename(saved_test_command, test_command) |
|
TVL
2009/03/27 20:04:31
do you want an exception handler on any of this to
|
| + |
| def ValgrindCommand(self): |
| """Get the valgrind command to run.""" |
| proc = ["valgrind", "--smc-check=all", "--leak-check=full", |