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 81 82 83 84 85
|
#! /usr/bin/env python
#
# The purpose of this python program is to scan through valgrind runs
# looking for memory leaks or bad exit statuses.
#
# It takes a list of executables to run through valgrind.
from os import popen
from sys import stdout
from re import compile
from time import sleep
failedRuns = []
leakyRuns = []
definiteLeakedBytes = 0
definiteLeakedBlocks = 0
possibleLeakedBytes = 0
possibleLeakedBlocks = 0
def runValgrind(executable):
global failedRuns, definiteLeakedBytes, definiteLeakedBlocks
global possibleLeakedBytes, possibleLeakedBlocks, leakyRuns
errors = compile(r"^==\d+==\s+ERROR SUMMARY:\s+(\d+)\s+errors from\s+(\d+)\s+contexts")
definite = compile(r"^==\d+==\s+definitely lost:\s+(\d+)\s+bytes in\s+(\d+)\s+blocks.")
possible = compile(r"^==\d+==\s+possibly lost:\s+(\d+)\s+bytes in\s+(\d+)\s+blocks.")
if ((executable[0] != '/') and
(executable[0] != '.')):
executable = "./" + executable
print "Running", executable
run = popen("valgrind --leak-check=yes --show-reachable=yes ./" +
executable + " 2>&1")
line = run.readline()
while (line):
check = errors.match(line)
if check and eval(check.group(1)):
failedRuns = failedRuns + [ executable + " " + check.group(1) +
" errors in " + check.group(2) +
" contexts" ]
check = definite.match(line)
if check:
leakedBytes = eval(check.group(1))
leakedBlocks = eval(check.group(2))
definiteLeakedBytes = definiteLeakedBytes + leakedBytes
definiteLeakedBlocks = definiteLeakedBlocks + leakedBlocks
if leakedBytes:
leakyRuns = leakyRuns + [ executable + ' definitely leaked ' +
str(leakedBytes) + " bytes in " +
str(leakedBlocks) + " blocks." ]
check = possible.match(line)
if check:
leakedBytes = eval(check.group(1))
leakedBlocks = eval(check.group(2))
possibleLeakedBytes = possibleLeakedBytes + leakedBytes
possibleLeakedBlocks = possibleLeakedBlocks + leakedBlocks
if leakedBytes:
leakyRuns = leakyRuns + [ executable + ' possibly leaked ' +
str(leakedBytes) + " bytes in " +
str(leakedBlocks) + " blocks (possible)." ]
stdout.write(line)
line = run.readline()
sleep(0.2)
exitstatus = run.close();
if exitstatus:
print "Program", executable, "exited with status", exitstatus
failedRuns = failedRuns + [ executable + " " + str(exitstatus)]
def summarizeRun():
print "=============================="
print "SUMMARY OF VALGRIND RUNS"
print "=============================="
print len(failedRuns), "failed or had errors"
for i in failedRuns:
print ' ', i
print definiteLeakedBytes, "bytes leaked in", definiteLeakedBlocks, "blocks"
print possibleLeakedBytes, "bytes leaked in", possibleLeakedBlocks, "blocks"
for i in leakyRuns:
print ' ', i
if __name__ == '__main__':
from sys import argv
for i in argv[1:]:
runValgrind(i)
summarizeRun()
|