| #!/usr/bin/env python3 |
| # |
| # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| # for details. All rights reserved. Use of this source code is governed by a |
| # BSD-style license that can be found in the LICENSE file. |
| |
| # Simple wrapper for running Valgrind and checking the output on |
| # stderr for memory leaks. |
| |
| import subprocess |
| import sys |
| import re |
| |
| VALGRIND_ARGUMENTS = [ |
| 'valgrind', |
| '--error-exitcode=1', |
| '--leak-check=full', |
| '--trace-children=yes', |
| '--ignore-ranges=0x000-0xFFF', # Used for implicit null checks. |
| '--vex-iropt-level=1' # Valgrind crashes with the default level (2). |
| ] |
| |
| # Compute the command line. |
| command = VALGRIND_ARGUMENTS + sys.argv[1:] |
| |
| # Run Valgrind. |
| process = subprocess.Popen( |
| command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| code = process.wait() |
| output = process.stdout.readlines() |
| errors = process.stderr.readlines() |
| |
| # Always print the output, but leave out the 3 line banner printed |
| # by certain versions of Valgrind. |
| if len(output) > 0 and output[0].startswith("** VALGRIND_ROOT="): |
| output = output[3:] |
| sys.stdout.writelines(output) |
| |
| # If Valgrind produced an error, we report that to the user. |
| if code != 0: |
| sys.stderr.writelines(errors) |
| sys.exit(code) |
| |
| # Look through the leak details and make sure that we don't have |
| # any definitely or indirectly lost bytes. We allow possibly lost |
| # bytes to lower the risk of false positives. |
| LEAK_RE = r"(?:definitely|indirectly) lost:" |
| LEAK_LINE_MATCHER = re.compile(LEAK_RE) |
| LEAK_OKAY_MATCHER = re.compile(r"lost: 0 bytes in 0 blocks") |
| leaks = [] |
| for line in errors: |
| if LEAK_LINE_MATCHER.search(line): |
| leaks.append(line) |
| if not LEAK_OKAY_MATCHER.search(line): |
| sys.stderr.writelines(errors) |
| sys.exit(1) |
| |
| # Make sure we found the right number of leak lines. |
| if not len(leaks) in [0, 2, 3]: |
| sys.stderr.writelines(errors) |
| sys.stderr.write('\n\n#### Malformed Valgrind output.\n#### Exiting.\n') |
| sys.exit(1) |
| |
| # Success. |
| sys.exit(0) |