scripts: Added better cycles detection to stack.py

stack.py actually already had a simple cycle detector, since we needed
one to calculate stack limits without getting stuck.

Copying this simple cycle detector into the actual table rendering code
lets us print a nice little "cycle detected" message, instead of just
vomiting to stdout forever:

    $ ./scripts/stack.py lfs.ci lfs_util.ci -z -s
    function                       frame    limit
    lfsr_format                      320        ∞
    |-> lfsr_mountinited             304        ∞
    |   |-> lfsr_mountmroot           80        ∞
    |   |   |-> lfsr_mountmroot       80        ∞ (cycle detected)
    |   |   |-> lfsr_mdir_lookup      48      576
    ... snip ...

The cycle detector is a bit naive, just building a new set each step,
but it gets the job done.

As for perf.py and perfbd.py, it turns out they can't actually create
cycles, so no need for a cycle detector. This is good because I didn't
really want to test these scripts again :)
This commit is contained in:
Christopher Haster
2024-11-02 22:05:23 -05:00
parent bc587e7166
commit fc45af3f6e
3 changed files with 31 additions and 13 deletions

View File

@@ -828,12 +828,12 @@ def table(Result, results, diff_results=None, *,
widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1)
notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1]))
# adjust the name width based on the call depth
if not summary:
# find the actual depth
#
# note unlike stack.py we can't end up with cycles here
depth_ = depth
if m.isinf(depth_):
# find the actual depth, this may not terminate! in which
# case it's up to the user to provide an explicit depth
def rec_depth(results_):
# rebuild our tables at each layer
table_ = {
@@ -852,6 +852,7 @@ def table(Result, results, diff_results=None, *,
if name in table),
default=-1) + 1
# adjust the name width based on the call depth
widths[0] += 4*max(depth_-1, 0)
# print the tree recursively