def print_tree(self, p: Policy) -> None: """ NOTE: this function is called right before cctrace.py exits and only once. NOTE: this is a best effort to compactly represent the process tree. """ def keeper(n: CCNode) -> bool: """ Returns True if this node is interesting, False otherwise. """ # configure processes are never keepers if n.name.endswith("configure"): return False # prune children n.children = filter(lambda c: keeper(c), n.children) # boring leafs are never keepers if n.is_leaf and n.color in [Colors.DGRAY, Colors.NO_COLOR]: return False return True roots = [r for r in self.roots if keeper(r)] duplicates = set() forrest = [] # first remove duplicate subtrees for root in roots: for _, _, node in RenderTree(root, style=STY): marker = node.hash_subtree() if node.parent: marker = hash((marker, node.parent.hash_roots())) if marker in duplicates: par = node.parent if par: par.children = [c for c in par.children if c != node] else: duplicates.add(marker) # ... then print the forrest for root in roots: for pre, _, node in RenderTree(root, style=STY): ncolor = node.color # color policy-checked nodes green if p.is_checked(node.name) and p.check(node.name) is None: ncolor = Colors.LGREEN # line = "{}{}{}".format(pre, ncolor, node.name) line = "{}{}{} ({})".format(pre, ncolor, node.name, node.pid) # nodes representing compiler drivers have version information cc_ver = get_tool_ver(node.name) if cc_ver: line += Colors.DGRAY + " " + cc_ver line = line + Colors.NO_COLOR forrest.append(line) print("\n".join(forrest))