sc-forks / solidity-coverage

Code coverage for Solidity smart-contracts
MIT License
977 stars 264 forks source link

CompilerError: Stack too deep, try removing local variables. #248

Closed ekreda closed 5 years ago

ekreda commented 6 years ago

Hi I'm using solidity-coverage on a few contracts (all using default configuration) but on one of my contracts I'm getting: CompilerError: Stack too deep, try removing local variables. Compilation failed. See above.

Naturally the sol file compiled exception free when it's compiled not by solidity-coverage.

cgewecke commented 6 years ago

@ekreda Could you provide any more information about this? How many local variables are defined in that function?

ekreda commented 6 years ago

@cgewecke the max solidity allow (8)... My guess is when you compile the code you add at least one var to the function - hence the "CompilerError" created.

We managed to overcome this for now by refactoring our code and reduce the local variables as suggested - once done everything is working back as expected.

cgewecke commented 6 years ago

@ekreda Oh good, thanks for raising this.

For anyone else running into this there's discussion at Solidity here about how to address the problem under non-coverage conditions. TLDR; pack variables into structs.

area commented 6 years ago

This has caught my eye because I don't think we do inject variables - all our events use constants, unless I'm missing something. Are you able to share the code that is unable to be instrumented correctly?

alexaltair commented 6 years ago

I'm having this problem as well. We have a complex contract that has already had a bunch of local vars removed due to the limit, so unfortunately I don't think we can remove more for the purpose of coverage testing. (Also unfortunately I can't share the code right now.) I was hoping there might be a compiler flag to increase the limit, but I haven't found it yet.

alexaltair commented 6 years ago

@area I've isolated that the Stack too deep error happens before the contracts are even instrumented. Running truffle compile gives the same error, even though our test's call to solc successfully compiles them, for the same compiler version. This could explain why it's happening even if instrumentation doesn't inject variables.

alexaltair commented 6 years ago

Yep, it turned out that our tests were using using solc with the --optimize flag. @ekreda In case this is your problem too, I solved it by creating a truffle.js config file in accordance with this;

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*"
    },
    coverage: {
      host: "localhost",
      network_id: "*",
      port: 8555,
      gas: 0xfffffffffff,
      gasPrice: 0x01
    },
  }, // ^ Reproducing the solidity-coverage defaults
  solc: {
    optimizer: { // Turning on compiler optimization that removes some local variables during compilation
      enabled: true,
      runs: 200
    }
  }
};
k06a commented 4 years ago

Found a nice trick to avoid this issue: https://ethereum.stackexchange.com/a/83842/3032

endlessbuilder commented 2 years ago

I have also got this error. I am trying to fix this. if anyone have solution for this, please tell me.