Skip to content

Instantly share code, notes, and snippets.

@vinlin24
Last active February 5, 2023 04:52
Show Gist options
  • Save vinlin24/5104f224f8b58178eb72a81bc14e667a to your computer and use it in GitHub Desktop.
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
#!/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