Stefan Schuermans commited on 2020-05-23 16:38:21
Showing 4 changed files, with 59 additions and 10 deletions.
| ... | ... |
@@ -19,6 +19,29 @@ class Process(): |
| 19 | 19 |
self._parent = None |
| 20 | 20 |
self._children = list() |
| 21 | 21 |
|
| 22 |
+ @property |
|
| 23 |
+ def children(self) -> list: |
|
| 24 |
+ """ |
|
| 25 |
+ List of child processes. |
|
| 26 |
+ """ |
|
| 27 |
+ return self._children.copy() |
|
| 28 |
+ |
|
| 29 |
+ @property |
|
| 30 |
+ def cmdline(self) -> list: |
|
| 31 |
+ """ |
|
| 32 |
+ Command line of process. |
|
| 33 |
+ """ |
|
| 34 |
+ if self._begin is None: |
|
| 35 |
+ return None |
|
| 36 |
+ return self._begin.cmdline |
|
| 37 |
+ |
|
| 38 |
+ @property |
|
| 39 |
+ def parent(self): |
|
| 40 |
+ """ |
|
| 41 |
+ Parent process (or None). |
|
| 42 |
+ """ |
|
| 43 |
+ return self._parent |
|
| 44 |
+ |
|
| 22 | 45 |
def addChild(self, child): |
| 23 | 46 |
""" |
| 24 | 47 |
Add a child process. |
| ... | ... |
@@ -81,6 +104,13 @@ class Processes(uproctrace.parse.Visitor): |
| 81 | 104 |
# store event in timeline |
| 82 | 105 |
self._timeline.setdefault(event.timestamp, list()).append(event) |
| 83 | 106 |
|
| 107 |
+ @property |
|
| 108 |
+ def toplevel(self): |
|
| 109 |
+ """ |
|
| 110 |
+ List of toplevel processes. |
|
| 111 |
+ """ |
|
| 112 |
+ return self._toplevel_processes.copy() |
|
| 113 |
+ |
|
| 84 | 114 |
def visitProcBegin(self, proc_begin: uproctrace.parse.ProcBegin): |
| 85 | 115 |
""" |
| 86 | 116 |
Process a process begin event. |
| ... | ... |
@@ -3,7 +3,9 @@ Command line interface of UProcTrace: "upt-tool". |
| 3 | 3 |
""" |
| 4 | 4 |
|
| 5 | 5 |
import argparse |
| 6 |
+import shlex |
|
| 6 | 7 |
import sys |
| 8 |
+ |
|
| 7 | 9 |
import uproctrace.dump |
| 8 | 10 |
import uproctrace.processes |
| 9 | 11 |
|
| ... | ... |
@@ -17,12 +19,29 @@ def dump(args): |
| 17 | 19 |
pass |
| 18 | 20 |
|
| 19 | 21 |
|
| 20 |
-def parse(args): |
|
| 22 |
+def pstree(args): |
|
| 21 | 23 |
""" |
| 22 |
- Parse all events in trace file. |
|
| 24 |
+ Print process tree. |
|
| 23 | 25 |
""" |
| 24 | 26 |
with open(args.trace, 'rb') as proto_file: |
| 25 |
- uproctrace.processes.Processes(proto_file) |
|
| 27 |
+ processes = uproctrace.processes.Processes(proto_file) |
|
| 28 |
+ # tree output (iterative) |
|
| 29 |
+ to_be_output = [processes.toplevel] |
|
| 30 |
+ while to_be_output: |
|
| 31 |
+ procs = to_be_output[-1] |
|
| 32 |
+ if not procs: |
|
| 33 |
+ del to_be_output[-1] |
|
| 34 |
+ continue |
|
| 35 |
+ indent = ' ' * (len(to_be_output) - 1) |
|
| 36 |
+ proc = procs[0] |
|
| 37 |
+ del procs[0] |
|
| 38 |
+ cmdline = proc.cmdline |
|
| 39 |
+ if cmdline is None: |
|
| 40 |
+ cmdline_str = '???' |
|
| 41 |
+ else: |
|
| 42 |
+ cmdline_str = ' '.join([shlex.quote(s) for s in cmdline]) |
|
| 43 |
+ print(indent + cmdline_str) |
|
| 44 |
+ to_be_output.append(proc.children) |
|
| 26 | 45 |
|
| 27 | 46 |
|
| 28 | 47 |
def parse_args(): |
| ... | ... |
@@ -30,15 +49,15 @@ def parse_args(): |
| 30 | 49 |
Parse command line arguments. |
| 31 | 50 |
""" |
| 32 | 51 |
# set up main parser |
| 33 |
- parser = argparse.ArgumentParser(description='uproctrace tool') |
|
| 52 |
+ parser = argparse.ArgumentParser(description='UProcTrace tool.') |
|
| 34 | 53 |
parser.add_argument('trace', help='trace file')
|
| 35 | 54 |
subparsers = parser.add_subparsers() |
| 36 | 55 |
# dump |
| 37 |
- dump_parser = subparsers.add_parser('dump')
|
|
| 56 |
+ dump_parser = subparsers.add_parser('dump', help='Dump events to stdout.')
|
|
| 38 | 57 |
dump_parser.set_defaults(func=dump) |
| 39 |
- # parse |
|
| 40 |
- parse_parser = subparsers.add_parser('parse')
|
|
| 41 |
- parse_parser.set_defaults(func=parse) |
|
| 58 |
+ # pstree |
|
| 59 |
+ pstree_parser = subparsers.add_parser('pstree', help='Print process tree.')
|
|
| 60 |
+ pstree_parser.set_defaults(func=pstree) |
|
| 42 | 61 |
# parse |
| 43 | 62 |
args = parser.parse_args() |
| 44 | 63 |
if not hasattr(args, 'func'): |