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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#!/usr/bin/env python
import sys
import os
import re
from subprocess import Popen, PIPE
class LedgerHarness:
ledger = None
sourcepath = None
succeeded = 0
failed = 0
verify = False
gmalloc = False
def __init__(self, argv):
if not os.path.isfile(argv[1]):
print "Cannot find ledger at '%s'" % argv[1]
sys.exit(1)
if not os.path.isdir(argv[2]):
print "Cannot find source path at '%s'" % argv[2]
sys.exit(1)
self.ledger = argv[1]
self.sourcepath = argv[2]
self.succeeded = 0
self.failed = 0
self.verify = '--verify' in argv
self.gmalloc = '--gmalloc' in argv
def run(self, command, verify=None, gmalloc=None, columns=True):
env = os.environ.copy()
if (gmalloc is not None and gmalloc) or \
(gmalloc is None and self.gmalloc):
env['MallocGuardEdges'] = '1'
env['MallocScribble'] = '1'
env['MallocPreScribble'] = '1'
env['MallocCheckHeapStart'] = '1000'
env['MallocCheckHeapEach'] = '10000'
env['DYLD_INSERT_LIBRARIES'] = '/usr/lib/libgmalloc.dylib'
env['MALLOC_PROTECT_BEFORE'] = '1'
env['MALLOC_FILL_SPACE'] = '1'
env['MALLOC_STRICT_SIZE'] = '1'
if (verify is not None and verify) or \
(verify is None and self.verify):
insert = ' --verify'
else:
insert = ''
if columns:
insert += ' --columns=80'
command = re.sub('\$ledger', '%s%s %s' % \
(self.ledger, insert, '--args-only'), command)
return Popen(command, shell=True, close_fds=True, env=env,
stdin=PIPE, stdout=PIPE, stderr=PIPE)
def read(self, fd):
text = ""
text_data = os.read(fd.fileno(), 8192)
while text_data:
if text_data:
text += text_data
text_data = os.read(fd.fileno(), 8192)
if text_data:
text += text_data
return text
def readlines(self, fd):
lines = []
for line in fd.readlines():
if line == "GuardMalloc: Allocations will be placed on byte boundaries.\n" or \
line == "GuardMalloc: - Some buffer overruns may not be noticed.\n" or \
line == "GuardMalloc: - Applications using vector instructions (e.g., SSE or Altivec) may fail.\n" or \
line == "GuardMalloc: - Applications expecting word-aligned pointers may fail (such as Carbon applications)\n" or \
line == "GuardMalloc: GuardMalloc version 18\n":
continue
else:
lines.append(line)
return lines
def wait(self, process, msg='Ledger invocation failed:'):
if process.wait() != 0:
print msg
print process.stderr.read()
self.failure()
return False
return True
def success(self):
sys.stdout.write(".")
self.succeeded += 1
def failure(self):
sys.stdout.write("E")
self.failed += 1
def exit(self):
print
if self.succeeded > 0:
print "OK (%d) " % self.succeeded,
if self.failed > 0:
print "FAILED (%d)" % self.failed,
print
sys.exit(self.failed)
if __name__ == '__main__':
harness = LedgerHarness(sys.argv)
proc = harness.run('$ledger -f doc/sample.dat reg')
print 'STDOUT:'
print proc.stdout.read()
print 'STDERR:'
print proc.stderr.read()
harness.success()
harness.exit()
|