Skip to content

Commit c51f3ef

Browse files
authored
feat(pseudofiles): sort file failures by failure count (#558)
1 parent 4d1ed1f commit c51f3ef

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

pyplugins/interventions/pseudofiles.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,35 @@ def rwif(*args):
119119
return rwif
120120

121121

122+
def get_total_counts(d):
123+
"""Get the sum of all "count" values of a nested dictionary"""
124+
return (
125+
(
126+
d["count"]
127+
if "count" in d else
128+
sum(map(get_total_counts, d.values()))
129+
)
130+
if isinstance(d, dict) else 0
131+
)
132+
133+
134+
def sort_file_failures(d):
135+
"""Get a sorted version of the file failures dictionary."""
136+
# This relies on dict iteration being the same as insertion order,
137+
# which is an implementation detail in CPython,
138+
# but OrderedDict is harder to serialize with pyyaml.
139+
return (
140+
dict(
141+
sorted(
142+
((k, sort_file_failures(v)) for k, v in d.items()),
143+
key=lambda pair: get_total_counts(pair[1]),
144+
reverse=True,
145+
)
146+
)
147+
if isinstance(d, dict) else d
148+
)
149+
150+
122151
class FileFailures(PyPlugin):
123152
def __init__(self, panda):
124153
self.panda = panda
@@ -735,7 +764,8 @@ def ioctl_default(self, filename, cmd, arg, ioctl_details):
735764
def dump_results(self):
736765
# Dump all file failures to disk as yaml
737766
with open(pjoin(self.outdir, outfile_missing), "w") as f:
738-
yaml.dump(self.file_failures, f)
767+
out = sort_file_failures(self.file_failures)
768+
yaml.dump(out, f, sort_keys=False)
739769

740770
if hasattr(self, "symex"):
741771
# Need to tell symex to export results as well

0 commit comments

Comments
 (0)