| 24 | |
| 25 | @dataclass |
| 26 | class StraceResult: |
| 27 | strace_returncode: int |
| 28 | python_returncode: int |
| 29 | |
| 30 | """The event messages generated by strace. This is very similar to the |
| 31 | stderr strace produces with returncode marker section removed.""" |
| 32 | event_bytes: bytes |
| 33 | stdout: bytes |
| 34 | stderr: bytes |
| 35 | |
| 36 | def events(self): |
| 37 | """Parse event_bytes data into system calls for easier processing. |
| 38 | |
| 39 | This assumes the program under inspection doesn't print any non-utf8 |
| 40 | strings which would mix into the strace output.""" |
| 41 | decoded_events = self.event_bytes.decode('utf-8', 'surrogateescape') |
| 42 | matches = [ |
| 43 | _syscall_regex.match(event) |
| 44 | for event in decoded_events.splitlines() |
| 45 | ] |
| 46 | return [ |
| 47 | StraceEvent(match["syscall"], |
| 48 | [arg.strip() for arg in (match["args"].split(","))], |
| 49 | match["returncode"]) for match in matches if match |
| 50 | ] |
| 51 | |
| 52 | def sections(self): |
| 53 | """Find all "MARK <X>" writes and use them to make groups of events. |
| 54 | |
| 55 | This is useful to avoid variable / overhead events, like those at |
| 56 | interpreter startup or when opening a file so a test can verify just |
| 57 | the small case under study.""" |
| 58 | current_section = "__startup" |
| 59 | sections = {current_section: []} |
| 60 | for event in self.events(): |
| 61 | if event.syscall == 'write' and len( |
| 62 | event.args) > 2 and event.args[1].startswith("\"MARK "): |
| 63 | # Found a new section, don't include the write in the section |
| 64 | # but all events until next mark should be in that section |
| 65 | current_section = event.args[1].split( |
| 66 | " ", 1)[1].removesuffix('\\n"') |
| 67 | if current_section not in sections: |
| 68 | sections[current_section] = list() |
| 69 | else: |
| 70 | sections[current_section].append(event) |
| 71 | |
| 72 | return sections |
| 73 | |
| 74 | def _filter_memory_call(call): |
| 75 | # mmap can operate on a fd or "MAP_ANONYMOUS" which gives a block of memory. |
no outgoing calls
no test coverage detected
searching dependent graphs…