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'): |