-
Notifications
You must be signed in to change notification settings - Fork 17
/
valleak.py
executable file
·80 lines (65 loc) · 2.34 KB
/
valleak.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/python
# Exit with an error code if Valgrind finds "definitely lost" memory.
import os
import subprocess
import sys
import tempfile
VALGRIND = "valgrind"
def valleak(executable):
"""Returns (error, stdout, stderr).
error == 0 if successful, an integer > 0 if there are memory leaks or errors."""
valgrind_output = tempfile.NamedTemporaryFile()
# Figure out the version of valgrind since command line arguments vary
valgrind = subprocess.Popen((VALGRIND, "--version"),
stdout = subprocess.PIPE)
valgrind_version = valgrind.stdout.read()
log_argument = "--log-file"
if valgrind_version.startswith("valgrind-3.2"):
log_argument = "--log-file-exactly"
valgrind_command = (
VALGRIND,
"--leak-check=full",
log_argument + "=" + valgrind_output.name,
"--error-exitcode=1",
executable)
process = subprocess.Popen(
valgrind_command,
bufsize = -1,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
close_fds = True)
process.stdin.close()
stdout = process.stdout.read()
stderr = process.stderr.read()
error = process.wait()
valgrind_error_file = open(valgrind_output.name)
valgrind_error = valgrind_error_file.read()
valgrind_error_file.close()
valgrind_output.close()
# Find the last summary block in the valgrind report
# This ignores forks
summary_start = valgrind_error.rindex("== ERROR SUMMARY:")
summary = valgrind_error[summary_start:]
append_valgrind = False
if error == 0:
assert "== ERROR SUMMARY: 0 errors" in summary
# Check for memory leaks
if "== definitely lost:" in summary:
error = 1
append_valgrind = True
elif "== ERROR SUMMARY: 0 errors" not in summary:
# We also have valgrind errors: append the log to stderr
append_valgrind = True
if append_valgrind:
stderr = stderr + "\n\n" + valgrind_error
return (error, stdout, stderr)
if __name__ == "__main__":
if len(sys.argv) != 2:
sys.stderr.write("valleak.py [executable]\n")
sys.exit(1)
exe = sys.argv[1]
error, stdin, stderr = valleak(exe)
sys.stdout.write(stdin)
sys.stderr.write(stderr)
sys.exit(error)