-
-
Save vinlin24/5104f224f8b58178eb72a81bc14e667a to your computer and use it in GitHub Desktop.
(CS 111 Lab 1) Script for filtering strace output to only show system calls you used
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/env python3 | |
# -*- coding: utf-8 -*- | |
"""parse_trace.py | |
Script for parsing an strace file. | |
""" | |
import re | |
from collections import defaultdict | |
__author__ = "Vincent Lin" | |
def get_command_name(execve_line: str) -> str: | |
match = re.search(r'^execve\(".+", \["(.+)"\].*', execve_line) | |
if match is None: | |
raise Exception("Could not match execve regex") | |
return match.group(1) | |
with open("trace.log", "rt", encoding="utf-8") as fp: | |
lines = fp.readlines() | |
pids_to_calls = defaultdict(list) | |
for line_num, line in enumerate(lines, start=1): | |
pid, rest = line.split(maxsplit=1) | |
pids_to_calls[pid].append((line_num, rest)) | |
ppid, *cpids = pids_to_calls.keys() | |
ppid_calls = pids_to_calls[ppid] | |
# Get to the first pipe() | |
for clone_index, (line_num, line) in enumerate(ppid_calls): | |
if line.startswith("pipe("): | |
break | |
else: | |
raise Exception("Couldn't find the first pipe() in parent trace") | |
# Now add all the system calls we made | |
our_ppid_calls = [] | |
sys_call_names = ["pipe", "clone", "wait4", "close"] | |
# These can be unfinished, so look for "resumed" messages too | |
resumed_names = [f"<... {name} resumed>" for name in sys_call_names] | |
sys_call_names.extend(resumed_names) | |
for i in range(clone_index, len(ppid_calls)): | |
line_num, call = ppid_calls[i] | |
if any(call.startswith(s) for s in sys_call_names): | |
our_ppid_calls.append((line_num, call)) | |
print(f"PARENT (PID: {ppid}):\n") | |
print("".join(f"{lineno}:{call}" for lineno, call in our_ppid_calls)) | |
# Repeat for each child, but look out for redirection calls too | |
for cpid in cpids: | |
cpid_calls = pids_to_calls[cpid] | |
our_cpid_calls = [] | |
# For child processes, our calls are everything before execve | |
command_name = "?" | |
for line_num, line in cpid_calls: | |
if line.startswith("execve("): | |
command_name = get_command_name(line) | |
break | |
our_cpid_calls.append((line_num, line)) | |
print(f"CHILD [{command_name}] (PID: {cpid}):\n") | |
print("".join(f"{lineno}:{call}" for lineno, call in our_cpid_calls)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment