Skip to content

Log shrinking status#1454

Merged
gustavo-grieco merged 9 commits intocrytic:masterfrom
BowTiedRadone:feat/shrinking-step-logging
Oct 9, 2025
Merged

Log shrinking status#1454
gustavo-grieco merged 9 commits intocrytic:masterfrom
BowTiedRadone:feat/shrinking-step-logging

Conversation

@BowTiedRadone
Copy link
Copy Markdown
Contributor

@BowTiedRadone BowTiedRadone commented Sep 18, 2025

This PR adds shrinking info in the "detached mode" as requested in #1270. This feature displays real-time shrinking progress in the status line as: W{id}:N/M (P) where N is the current step, M is the limit, P is the current reproducer length, and id is the corresponding worker id.

Sample status line:

[2025-10-07 18:30:24.70] [status] tests: 1/2, fuzzing: 423146/1000000, values: [], cov: 513, corpus: 6, shrinking: W2:4592/5000(23), gas/s: 365760896

To see shrinking progress, run:

echidna <args> | tee /tmp/logs 

A worker event is also logged showing the shrinking operation and the sequence
length before and after each successful step.
@gustavo-grieco
Copy link
Copy Markdown
Collaborator

Hi,

Thanks for starting this PR! I think we should follow @aviggiano advise, let's avoid adding the last operation, as it looks overkill.

@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

@gustavo-grieco Thanks for the feedback! Will remove last operation from the status line. That will also simplify the diff a lot. Just brainstorming logShrinking: instead of a simple on/off, what do you think about making it a level? For example:

  • Off: no output (default)
  • Status: status line only (shrinking: N/M (P))
  • Verbose: status line + per-step details (before → after, op)

@gustavo-grieco
Copy link
Copy Markdown
Collaborator

If the output is small and unintrusive, this can be enable by default. It will be only be triggered when using the text mode and when an invariant is failing.

@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

If the output is small and unintrusive, this can be enable by default. It will be only be triggered when using the text mode and when an invariant is failing.

@gustavo-grieco done in 44f65d6 + 6188d78. The latest version always displays shrinking info in the status line. The "very-verbose" step logs are still hidden by the logShrinking flag.

@BowTiedRadone BowTiedRadone marked this pull request as ready for review September 24, 2025 12:01
@BowTiedRadone BowTiedRadone changed the title [DRAFT] Log shrinking status Log shrinking status Sep 24, 2025
, runningThreads :: [ThreadId]
-- ^ Extra threads currently being run,
-- aside from the main worker thread
, lastShrinkP :: Maybe Int
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need this field? Can you calculate it each time from the reproducer size?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gustavo-grieco Good catch! The diff is much more shrinked now 😄 (5c8b253)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks very good!, let me test this and we can merge it next week.

@gustavo-grieco
Copy link
Copy Markdown
Collaborator

@aviggiano @rappie can you provide some testing for this PR?

aviggiano added a commit to aviggiano/shrinking-mwe that referenced this pull request Oct 3, 2025
@aviggiano
Copy link
Copy Markdown

aviggiano commented Oct 3, 2025

Hey, I think I found a bug

https://gist.github.com/aviggiano/a52c44a823cffc443ca1f37cdaf47fdc

  1. When 2 or more workers are shrinking in parallel, the shrinking log will only display the results of the first worker
  2. When 2 or more workers are shrinking in series (ie, the first bug is falsified, shrinking happens, then a second bug is falsified), the shrinking log will not be updated; it will always show the first instance as it finishes, so M/M (P))

I updated shrinking-mwe with 2 invariants so that this is clearer

I guess the behavior of >1 shrinking was not specified, so we should think about what should happen on the first bullet

@gustavo-grieco
Copy link
Copy Markdown
Collaborator

Good catch, thanks a lot @aviggiano for the testing !

@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

BowTiedRadone commented Oct 3, 2025

@aviggiano Thanks for the testing and for sharing the logs!

The decision to implement shrinking data display this way was that status line only includes aggregated data at this point. However, did not count for the second bullet. I think a solution to this would be per-worker display:

shrinking: W1:1330/5000(39) W3:2730/5000(37)

This would show each worker's progress individually: W{id}:{step}/{limit}({length}). This fixes both issues:

  • Parallel workers: Each worker's progress is clearly visible instead of just the first one
  • Stale display: Only shows workers that are actively shrinking (step < limit), so completed workers automatically disappear from the display

@gustavo-grieco
Copy link
Copy Markdown
Collaborator

@BowTiedRadone I think your fix looks reasonable, so feel free to go ahead and we will review it as soon as you pushed it.

@BowTiedRadone BowTiedRadone force-pushed the feat/shrinking-step-logging branch from 2be9dbf to 971ef81 Compare October 6, 2025 23:16
@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

@gustavo-grieco 971ef81 seems to get the job done. Used @aviggiano's updates in shrinking-mwe to test it and looks good.

@rappie
Copy link
Copy Markdown

rappie commented Oct 7, 2025

This seems to be working great for me. I've stress tested it a little bit:

[2025-10-07 15:10:07.54] [status] tests: 11/50, fuzzing: 67137/100000000000, values: [], cov: 17133, corpus: 28, shrinking: W6:4324/5000(3) W9:1228/5000(5) W0:4021/5000(2) W8:1034/5000(6) W9:1227/5000(4) W4:3132/5000(4) W8:1034/5000(4) W0:4021/5000(4) W5:55/5000(22) W2:2793/5000(5) W1:3881/5000(3), gas/s: 15548858080
[2025-10-07 15:10:10.54] [status] tests: 11/50, fuzzing: 77666/100000000000, values: [], cov: 17133, corpus: 28, shrinking: W6:5000/5000(3) W9:1620/5000(3) W0:5000/5000(2) W8:1323/5000(6) W9:1620/5000(4) W4:3968/5000(4) W8:1323/5000(4) W0:5000/5000(4) W5:1142/5000(4) W2:3737/5000(5) W1:5000/5000(3), gas/s: 17178215539
[2025-10-07 15:10:13.54] [status] tests: 11/50, fuzzing: 97627/100000000000, values: [], cov: 17133, corpus: 28, shrinking: W6:5000/5000(3) W9:2123/5000(3) W0:5000/5000(2) W8:1605/5000(6) W9:2123/5000(4) W4:4813/5000(4) W8:1605/5000(4) W0:5000/5000(4) W5:2473/5000(4) W2:4642/5000(5) W1:5000/5000(3), gas/s: 32508100917
[2025-10-07 15:10:16.55] [status] tests: 11/50, fuzzing: 122226/100000000000, values: [], cov: 17133, corpus: 28, shrinking: W6:5000/5000(3) W9:2615/5000(3) W0:5000/5000(2) W8:1893/5000(6) W9:2614/5000(4) W4:5000/5000(4) W8:1893/5000(4) W0:5000/5000(4) W5:3791/5000(4) W2:5000/5000(5) W1:5000/5000(3), gas/s: 40358727267

No issues or crashes. Great work! 🙌

Question: Would it make sense to remove fully shrunk sequences? In the end my output looks like this, which adds a lot of unnecessary bulk:

[2025-10-07 15:10:40.57] [status] tests: 11/50, fuzzing: 376389/100000000000, values: [], cov: 17133, corpus: 28, shrinking: W6:5000/5000(3) W9:5000/5000(3) W0:5000/5000(2) W8:4175/5000(6) W9:5000/5000(4) W4:5000/5000(4) W8:4174/5000(4) W0:5000/5000(4) W5:5000/5000(4) W2:5000/5000(5) W1:5000/5000(3), gas/s: 55273269777

@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

@rappie Thanks for testing the PR! Your proposed approach sounds good. Just double checking before pushing your proposed suggestion. Are we okay with the following?

[2025-10-07 18:30:24.70] [status] tests: 1/2, fuzzing: 423146/1000000, values: [], cov: 513, corpus: 6, shrinking: W2:4592/5000(23), gas/s: 365760896
# W2 reaches max shrinking steps, shrinking status becomes `N/A` again:
[2025-10-07 18:30:27.71] [status] tests: 1/2, fuzzing: 513683/1000000, values: [], cov: 513, corpus: 6, shrinking: N/A, gas/s: 684749936

...

# Second invariant is falsified, only the worker that shrinks the reproducer will be included in the status line (since the previous one finished shrinking):
[2025-10-07 18:30:41.06]  Saved reproducer to echidna/reproducers-unshrunk/3298828898765790914.txt
[2025-10-07 18:30:42.98] [status] tests: 2/2, fuzzing: 817862/1000000, values: [], cov: 513, corpus: 6, shrinking: W0:545/5000(43), gas/s: 297850634
[2025-10-07 18:30:45.99] [status] tests: 2/2, fuzzing: 817862/1000000, values: [], cov: 513, corpus: 6, shrinking: W0:1076/5000(43), gas/s: 0

@rappie
Copy link
Copy Markdown

rappie commented Oct 7, 2025

Looks good to me.

Slightly more minimalistic alternative (mild preference): only show shrinking if there's shrinking taking place

@aviggiano
Copy link
Copy Markdown

Same, minimalistic is preferred
Looks good to me.

@BowTiedRadone
Copy link
Copy Markdown
Contributor Author

@rappie @aviggiano Done in 6c4c26c.

@rappie
Copy link
Copy Markdown

rappie commented Oct 9, 2025

Works great. Thanks 🙂

@aviggiano
Copy link
Copy Markdown

LGTM!

@gustavo-grieco gustavo-grieco merged commit 00f14cc into crytic:master Oct 9, 2025
15 checks passed
@gustavo-grieco
Copy link
Copy Markdown
Collaborator

Merged, thanks to everyone in the community for the code and testing!

datradito pushed a commit to datradito/echidna-mcp that referenced this pull request Dec 29, 2025
* Add cli option to include shrinking status in status lines

A worker event is also logged showing the shrinking operation and the sequence
length before and after each successful step.

* Add `logShrinking` flag to `default.yaml`

* Remove last shrinking op from status line

* Always display shrinking info in status line

* Comment cleanup

* Remove shrinking step log and `logShrinking` flag

* Compute status line reproducer length on demand

* Log per-worker shrinking status

* Display shrinking status when shrinking and active shrinking workers data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants