Created
February 11, 2016 06:13
-
-
Save lhchavez/b90b92c5ded9081956bc to your computer and use it in GitHub Desktop.
strace wrapper to display the read/written files of a process tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import argparse | |
import collections | |
import os | |
import os.path | |
import re | |
import subprocess | |
import sys | |
import threading | |
def readpipe(summary, directories): | |
forkre = re.compile(r'(\d+) .*fork.* =\s+(.*)') | |
syscallre = re.compile(r'(\d+) ([a-z]+)\((.*)\)\s+=\s+(.*)') | |
cwd = collections.defaultdict(lambda: os.getcwd()) | |
reads = collections.defaultdict(set) | |
writes = collections.defaultdict(set) | |
fds = collections.defaultdict(dict) | |
with open('.pipe', 'r') as fifo: | |
for line in fifo: | |
m = forkre.match(line) | |
if m != None: | |
pid, retval = m.groups() | |
cwd[int(retval)] = cwd[pid] | |
continue | |
m = syscallre.match(line) | |
if not m: continue | |
pid, syscall, args, retval = m.groups() | |
pid = int(pid) | |
if retval.startswith('-1'): continue | |
if syscall == 'chdir': | |
cwd[pid] = os.path.abspath(os.path.join(cwd[pid], args.strip('"'))) | |
elif syscall == 'open': | |
filename, flags = args.split(', ')[:2] | |
filename = os.path.abspath(os.path.join(cwd[pid], filename.strip('"'))) | |
fds[pid][int(retval)] = filename | |
if 'O_CREAT' in flags: | |
writes[pid].add(filename) | |
else: | |
reads[pid].add(filename) | |
elif syscall == 'creat': | |
filename = args.split(', ')[0].strip('"') | |
fds[pid][int(retval)] = filename | |
writes[pid].add(filename) | |
elif syscall == 'close': | |
if int(args) in fds[pid]: | |
del fds[pid][int(args)] | |
elif syscall == 'openat': | |
fd, filename, flags = args.split(', ')[:3] | |
if fd == 'AT_FDCWD': | |
filename = os.path.abspath(os.path.join(cwd[pid], filename.strip('"'))) | |
else: | |
filename = os.path.abspath(os.path.join(fds[pid][int(fd)], | |
filename.strip('"'))) | |
fds[pid][int(retval)] = filename | |
if 'O_CREAT' in flags: | |
writes[pid].add(filename) | |
else: | |
reads[pid].add(filename) | |
if directories: | |
directories = map(os.path.abspath, directories) | |
if summary: | |
sreads = set() | |
swrites = set() | |
for pid in cwd.keys(): | |
sreads.update(reads[pid]) | |
swrites.update(writes[pid]) | |
print 'reads:' | |
for r in sreads: | |
if directories and not any([r.startswith(d) for d in directories]): | |
continue | |
print '\t%s' % r | |
print 'writes:' | |
for w in swrites: | |
if directories and not any([w.startswith(d) for d in directories]): | |
continue | |
print '\t%s' % w | |
else: | |
for pid in cwd.keys(): | |
print pid | |
print '\treads:' | |
for r in reads[pid]: | |
if directories and not any([r.startswith(d) for d in directories]): | |
continue | |
print '\t\t%s' % r | |
print '\twrites:' | |
for w in writes[pid]: | |
if directories and not any([w.startswith(d) for d in directories]): | |
continue | |
print '\t\t%s' % w | |
def main(): | |
parser = argparse.ArgumentParser( | |
description='Inspect all opened files from a process tree') | |
parser.add_argument('--include', metavar='dir', type=str, dest='directories', | |
nargs='+', help='Only include files under the specified directories') | |
parser.add_argument('--summary', default=False, action='store_true', | |
help='Print a summary of all files read/written to') | |
parser.add_argument('args', metavar='arg', type=str, nargs='+', | |
help='The command to be executed') | |
args = parser.parse_args() | |
try: | |
os.mkfifo('.pipe') | |
thread = threading.Thread(target=readpipe, | |
args=(args.summary, args.directories,)) | |
thread.start() | |
subprocess.check_call(['/usr/bin/strace', '-f', '-e', | |
'trace=fork,vfork,creat,open,chdir,openat,close', | |
'-o', '.pipe'] + args.args) | |
finally: | |
os.unlink('.pipe') | |
if __name__ == '__main__': | |
sys.exit(main()) | |
# vim: set expandtab:ts=2:sw=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment