summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/scripts
diff options
context:
space:
mode:
authorSergey Matveev <earthdok@google.com>2014-05-19 12:53:03 +0000
committerSergey Matveev <earthdok@google.com>2014-05-19 12:53:03 +0000
commitb6f83acd39379c65b8a7c0823e63f417d968be8e (patch)
tree7140d62b02de0c7b9202016caa3c3bd3096803f1 /lib/sanitizer_common/scripts
parentaed089cf1e12ccf3e603ecf28a901d6eea1df4aa (diff)
[sanitizer] Support sandboxing in sanitizer coverage.
Summary: Sandboxed code may now pass additional arguments to __sanitizer_sandbox_on_notify() to force all coverage data to be dumped to a single file (the default is one file per module). The user may supply a file or socket to write to. The latter option can be used to broker out the file writing functionality. If -1 is passed, we pre-open a file. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@209121 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/scripts')
-rwxr-xr-xlib/sanitizer_common/scripts/sancov.py47
1 files changed, 40 insertions, 7 deletions
diff --git a/lib/sanitizer_common/scripts/sancov.py b/lib/sanitizer_common/scripts/sancov.py
index aa791bc4e..4354359b0 100755
--- a/lib/sanitizer_common/scripts/sancov.py
+++ b/lib/sanitizer_common/scripts/sancov.py
@@ -4,6 +4,7 @@
# We need to merge these integers into a set and then
# either print them (as hex) or dump them into another file.
import array
+import struct
import sys
prog_name = "";
@@ -11,16 +12,16 @@ prog_name = "";
def Usage():
print >> sys.stderr, "Usage: \n" + \
" " + prog_name + " merge file1 [file2 ...] > output\n" \
- " " + prog_name + " print file1 [file2 ...]\n"
+ " " + prog_name + " print file1 [file2 ...]\n" \
+ " " + prog_name + " unpack file1 [file2 ...]\n"
exit(1)
def ReadOneFile(path):
- f = open(path, mode="rb")
- f.seek(0, 2)
- size = f.tell()
- f.seek(0, 0)
- s = set(array.array('I', f.read(size)))
- f.close()
+ with open(path, mode="rb") as f:
+ f.seek(0, 2)
+ size = f.tell()
+ f.seek(0, 0)
+ s = set(array.array('I', f.read(size)))
print >>sys.stderr, "%s: read %d PCs from %s" % (prog_name, size / 4, path)
return s
@@ -44,6 +45,36 @@ def MergeAndPrint(files):
a = array.array('I', s)
a.tofile(sys.stdout)
+
+def UnpackOneFile(path):
+ with open(path, mode="rb") as f:
+ print >> sys.stderr, "%s: unpacking %s" % (prog_name, path)
+ while True:
+ header = f.read(12)
+ if not header: return
+ if len(header) < 12:
+ break
+ pid, module_length, blob_size = struct.unpack('iII', header)
+ module = f.read(module_length)
+ blob = f.read(blob_size)
+ assert(len(module) == module_length)
+ assert(len(blob) == blob_size)
+ extracted_file = "%s.%d.sancov" % (module, pid)
+ print >> sys.stderr, "%s: extracting %s" % \
+ (prog_name, extracted_file)
+ # The packed file may contain multiple blobs for the same pid/module
+ # pair. Append to the end of the file instead of overwriting.
+ with open(extracted_file, 'ab') as f2:
+ f2.write(blob)
+ # fail
+ raise Exception('Error reading file %s' % path)
+
+
+def Unpack(files):
+ for f in files:
+ UnpackOneFile(f)
+
+
if __name__ == '__main__':
prog_name = sys.argv[0]
if len(sys.argv) <= 2:
@@ -52,5 +83,7 @@ if __name__ == '__main__':
PrintFiles(sys.argv[2:])
elif sys.argv[1] == "merge":
MergeAndPrint(sys.argv[2:])
+ elif sys.argv[1] == "unpack":
+ Unpack(sys.argv[2:])
else:
Usage()