Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(forge coverage): stack too deep when using --ir-minimum #3357

Open
2 tasks done
uranium93 opened this issue Sep 25, 2022 · 23 comments · Fixed by #5349
Open
2 tasks done

bug(forge coverage): stack too deep when using --ir-minimum #3357

uranium93 opened this issue Sep 25, 2022 · 23 comments · Fixed by #5349
Labels
C-forge Command: forge Cmd-forge-coverage Command: forge coverage T-bug Type: bug T-post-V1 Area: to tackle after V1

Comments

@uranium93
Copy link

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (ddaf100 2022-09-24T00:05:44.382307Z)

What command(s) is the bug in?

forge coverage

Operating System

macOS (Apple Silicon)

Describe the bug

on executing forge coverage i am getting the below error

Error: 
Compiler run failed
CompilerError: Stack too deep when compiling inline assembly: Variable headStart is 1 slot(s) too deep inside the stack.

but forge test and forge build are working fine.

NOTE: I noticed also that forge build and forge test are considering the cache but forge coverage is trying to re-compile even though I have a cached successful build

@uranium93 uranium93 added the T-bug Type: bug label Sep 25, 2022
@gakonst gakonst added this to Foundry Sep 25, 2022
@gakonst gakonst moved this to Todo in Foundry Sep 25, 2022
@rkrasiuk rkrasiuk added C-forge Command: forge Cmd-forge-coverage Command: forge coverage labels Sep 26, 2022
@Rubilmax
Copy link
Contributor

Rubilmax commented Oct 31, 2022

Hi @onbjerg @mattsse, do you have any lead on this?

The bug also happens to us @ Morpho Labs

@mds1
Copy link
Collaborator

mds1 commented Oct 31, 2022

AFAIK forge coverage currently compiles with the optimizer off, which is needed for better source maps. forge test (and build) work because you're using the optimizer or via-IR which resolve the stack too deep error that's occurring with the optimizer off (this is also why you see it recompile for coverage).

Unfortunately for now to use coverage you'll need to refactor such that you can compile with the optimizer off / without via-IR

@Rubilmax
Copy link
Contributor

Rubilmax commented Oct 31, 2022

Understood, thanks! Is this issue thus nullified?

Would it be possible to have more information on where the Stack Too Deep error occurs in the source code pls?

@mds1
Copy link
Collaborator

mds1 commented Oct 31, 2022

Is this issue thus nullified?

I think this is a question for @uranium93? But yes I'd say this is a known issue/limitation so we can close this

Would it be possible to have more information on where the Stack Too Deep error occurs in the source code pls?

Unfortunately not, as solc does not provide this information since it's complex to retrieve. You can read more here: ethereum/solidity#11638 (comment)

@Rubilmax
Copy link
Contributor

Thank you!

@emo-eth
Copy link
Contributor

emo-eth commented Nov 2, 2022

I understand the reasoning for compiling without the optimizer – but I will note that this means currently any project that imports Seaport contracts directly cannot use forge coverage, as some assembly results in stack-too-deep errors.

There's probably not much to do at the moment – but we'd love if we could encourage new projects to build on top of Seaport with Foundry (including coverage) in the future.

@uranium93
Copy link
Author

Hey @Rubilmax , for me the only fix that was possible and fast is to re-write the affected tests with hardhat

@PaulRBerg
Copy link
Contributor

PaulRBerg commented Feb 7, 2023

@uranium93 structs are a neat way to solve Stack Too Deep.

@FlokiBB
Copy link

FlokiBB commented Mar 24, 2023

Hi Matt, is this issue still unresolved? I would be happy to work on it.

@mds1

@mds1
Copy link
Collaborator

mds1 commented Mar 24, 2023

This is still the case, however this is not easy to resolve in forge due to the current coverage limitations (which themselves are due to solc limitations). The easiest solution is to update your code to avoid stack too deep issues

@jat9292
Copy link

jat9292 commented Apr 24, 2023

Sorry, this is not a well-informed idea (I do not really know foundry internals tbh) but maybe a quick fix for this issue could be to add an optional flag to raise stack limit only when computing coverage?
I do not know how complex this would be.

@uranium93
Copy link
Author

@PaulRBerg @mds1 The issue is not about stack too deep, the issue as I described is miss-configuration and a behavioral mismatch between build, test, and coverage. The tool MUST have the same behaviors.

For everyone, the fix I applied was to combine both foundry and hardhat (use hardhat instead of foundry for whatever tests causing coverage to fail with this error), a bit more work but it works if you need to report the code coverage

@valo
Copy link

valo commented Jun 20, 2023

I managed to reliably reproduce by running forge coverage on https://github.com/connext/monorepo/tree/56defa5289003ef03b52d00dde750885757833e6/packages/deployments/contracts

The issue in the solidity compiler is being tracked here ethereum/solidity#11638

@spockP
Copy link
Contributor

spockP commented Jul 2, 2023

Looks like there will be a remedy when solidity 0.8.21 comes out: ethereum/solidity#13972

@aviggiano
Copy link

For future readers:

This workaround is better than --ir-minimum:

taikoxyz/taiko-mono#14489

aviggiano added a commit to SizeCredit/size-solidity that referenced this issue Jan 3, 2024
@ohaponiuk
Copy link

In my case --ir-minimum doesn't work, only makes the error more sophisticated:

Compiler run failed:
Error: Yul exception:Cannot swap Variable value16 with Slot 0x14: too deep in the stack by 2 slots in [ RET value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x14 ]
memoryguard was present.
memoryguard was present.

The solution that @aviggiano linked is for some specific blockchain as far as I can tell? Could be wrong.

Overall, I think we should reopen the issue as it's not solved yet.

@moyaying
Copy link

moyaying commented Feb 19, 2024

hi, @mattsse @spockP --ir-minimum doesn't work too

[⠒] Compiling...  
[⠆] Compiling 229 files with 0.8.22. 
[⠔] Solc 0.8.22 finished in 44.34s. 
Error: 
Compiler run failed:
Error: Yul exception:Cannot swap Variable var_fixturePoolEthereumUSDT_mpos with Variable var_fixturePoolBinanceUSDT_mpos: too deep in the stack by 3 slots in [ RET var_eidBinance var_eidBinance var_fixturePoolEthereumUSDT_mpos var_fixturePoolBinanceETH_mpos var_eidBinance var_fixturePoolBinanceETH_mpos var_fixturePoolEthereumETH_mpos var_eidEthereum var_fixturePoolEthereumUSDT_mpos var_eidEthereum var_eidEthereum var_fixturePoolEthereumETH_mpos var_fixturePoolEthereumETH_mpos var_eidEthereum var_assetETH var_assetUSDT var_eidEthereum var_eidBinance var_eidEthereum var_fixturePoolBinanceETH_mpos var_eidPolygon var_fixturePoolBinanceUSDT_mpos ]
No memoryguard was present. Consider using memory-safe assembly only and annotating it via 'assembly ("memory-safe") { ... }'.
No memoryguard was present. Consider using memory-safe assembly only and annotating it via 'assembly ("memory-safe") { ... }'.

@andreitoma8
Copy link

Hey! Same issue for me. I think the issue should be re-opened,

$ forge coverage --report lcov --ir-minimum
Warning! "--ir-minimum" flag enables viaIR with minimum optimization, which can result in inaccurate source mappings.
Only use this flag as a workaround if you are experiencing "stack too deep" errors.
Note that "viaIR" is only available in Solidity 0.8.13 and above.
See more:
https://github.com/foundry-rs/foundry/issues/3357

[⠊] Compiling...
[⠑] Compiling 265 files with 0.8.23
[⠔] Solc 0.8.23 finished in 437.62s
Error: 
Compiler run failed:
Error: Yul exception:Variable expr_13 is 1 too deep in the stack [ RET expr_13 expr expr_1 expr_3 expr_156548_address expr_156565_functionSelector expr_12 expr_156600_functionSelector expr_14 expr_156644_functionSelector expr_4 expr_156584_functionSelector expr_156624_functionSelector _70 expr_18 expr_156611_functionSelector _72 ]
memoryguard was present.
memoryguard was present.

@0xlxy
Copy link

0xlxy commented Mar 8, 2024

forge coverage --ir-minimum works for me.

$forge coverage --ir-minimum
Warning! "--ir-minimum" flag enables viaIR with minimum optimization, which can result in inaccurate source mappings.
Only use this flag as a workaround if you are experiencing "stack too deep" errors.
Note that "viaIR" is only available in Solidity 0.8.13 and above.
See more: https://github.com/foundry-rs/foundry/issues/3357
[⠊] Compiling...
[⠒] Compiling 49 files with 0.8.19
[⠆] Solc 0.8.19 finished in 8.46s
Compiler run successful!
Analysing contracts...
Running tests...
| File                                | % Lines          | % Statements     | % Branches     | % Funcs        |
|-------------------------------------|------------------|------------------|----------------|----------------|
|                                     |                  |                  |                |                |  

@sebastiantf
Copy link

vouching for reopening this issue

@jacob-abe
Copy link

This should definitely be reopened as its not really brought into light anywhere in the docs, don't need to resolve it. Just something for developers to have a heads up about before going with foundry for coverage.

@sebastiantf
Copy link

Would this be resolved if there was a version of Solidity and/or EVM (that the tests run on) which does not have the stack access limitation? Is that possible?

@shisukeUrahara
Copy link

I am also facing this issue. I have a big account abstraction foundry project .

1.) running forge coverage gives me this error

Error:
Compiler run failed:
Error: Compiler error (C:\Users\circleci\project\libyul\backends\evm\AsmCodeGen.cpp:67):Stack too deep. Try compiling with --via-ir (cli) or the equivalent viaIR: true (standard JSON) while enabling the optimizer. Otherwise, try removing local
variables. When compiling inline assembly: Variable value0 is 1 slot(s) too deep inside the stack. Stack too deep. Try compiling with --via-ir (cli) or the equivalent viaIR: true (standard JSON) while enabling the optimizer. Otherwise, try removing local variables.
CompilerError: Stack too deep. Try compiling with --via-ir (cli) or the equivalent viaIR: true (standard JSON) while enabling the optimizer. Otherwise, try removing local variables. When compiling inline assembly: Variable value0 is 1 slot(s) too deep inside the stack. Stack too deep. Try compiling with --via-ir (cli) or the equivalent viaIR: true (standard JSON) while enabling the optimizer. Otherwise, try removing local variables.

2.) running forge coverage --ir-minimum gives me this error

forge coverage --ir-minimum
Warning! "--ir-minimum" flag enables viaIR with minimum optimization, which can result in inaccurate source mappings.
Only use this flag as a workaround if you are experiencing "stack too deep" errors.
Note that "viaIR" is only available in Solidity 0.8.13 and above.
See more: #3357
[⠊] Compiling...
[⠒] Compiling 179 files with Solc 0.8.23
[⠰] Solc 0.8.23 finished in 56.14s
Compiler run successful with warnings:
Warning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.
--> contracts/base/ExecutionHelper.sol:111:33:
|
111 | ) internal virtual returns (bool success, bytes memory result) {
| ^^^^^^^^^^^^

Analysing contracts...
The application panicked (crashed).
Message: byte index 1762 is not a char boundary; it is inside '─' (bytes 1760..1763) of `// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;

library AxirStorage {
//keccak256('axir.contracts.AxirStorage')
bytes32 private constant AXIR_STORAGE_SLOT =
0x16b6c7591fc5ab5c74da74e00cae479996efc3fa685cfbb323b3175becf33`[...]
Location: crates\evm\coverage\src\analysis.rs:478

This is a bug. Consider reporting it at https://github.com/foundry-rs/foundry

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1: hid_write
at :
2: hid_write
at :
3: hid_write
at :
4: hid_write
at :
5: BaseThreadInitThunk
at :
6: RtlUserThreadStart
at :

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
Run with RUST_BACKTRACE=full to include source snippets.
The application panicked (crashed).

@zerosnacks zerosnacks reopened this Nov 15, 2024
@zerosnacks zerosnacks added the T-post-V1 Area: to tackle after V1 label Nov 15, 2024
@zerosnacks zerosnacks changed the title coverage stack too deep bug(forge coverage): stack too deep when using --ir-minimum Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge Cmd-forge-coverage Command: forge coverage T-bug Type: bug T-post-V1 Area: to tackle after V1
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.