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

Forge test debugger does not show sourcemaps for inherited contracts #7043

Closed
2 tasks done
emo-eth opened this issue Feb 8, 2024 · 3 comments · Fixed by #7058
Closed
2 tasks done

Forge test debugger does not show sourcemaps for inherited contracts #7043

emo-eth opened this issue Feb 8, 2024 · 3 comments · Fixed by #7058
Labels
T-bug Type: bug

Comments

@emo-eth
Copy link
Contributor

emo-eth commented Feb 8, 2024

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 (2cf84d9 2024-02-07T00:15:49.638525000Z)

What command(s) is the bug in?

forge test --debug

Operating System

None

Describe the bug

Sourcemaps for inherited contracts are not found/shown by the Forge test debugger.

In this case, the call to the inheriting contract is displayed correctly with sourcemap:
Screenshot 2024-02-07 at 4 54 49 PM

But once the function is dispatched to the inherited contract (JUMPI -> JUMPDEST), the debugger reports no sourcemap:
Screenshot 2024-02-07 at 4 55 27 PM

Code for minimal repro; run with forge clean; forge test --debug test_Increment. Tested with solc 0.8.13 and 0.8.23.

Counter.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract Counter {
    uint256 internal _number;

    event SetNumber(uint256 newNumber);
    event Increment();

    function setNumber(uint256 newNumber) public {
        emit SetNumber(newNumber);
        _number = newNumber;
    }

    function increment() public {
        emit Increment();
        ++_number;
    }

    function number() public view returns (uint256) {
        return _number;
    }

    function name() public view virtual returns (string memory) {
        return "Counter";
    }
}

AltCounter.sol (inheriting contract)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {Counter} from "src/Counter.sol";

contract AltCounter is Counter {
    function name() public view virtual override returns (string memory) {
        return "AltCounter";
    }
}

Counter.t.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {Test} from "forge-std/Test.sol";
import {Counter} from "src/Counter.sol";
import {AltCounter} from "src/AltCounter.sol";

contract CounterTest is Test {
    Counter public counter;

    function setUp() public {
        counter = new AltCounter();
        counter.setNumber(0);
    }

    function test_Increment() public {
        counter.increment();
        assertEq(counter.number(), 1);
    }

    function testFuzz_SetNumber(uint256 x) public {
        counter.setNumber(x);
        assertEq(counter.number(), x);
    }
}
@emo-eth emo-eth added the T-bug Type: bug label Feb 8, 2024
@emo-eth
Copy link
Contributor Author

emo-eth commented Feb 8, 2024

@DaniPopes any idea if this is related to #6522? I'm pretty sure it's been broken for longer, but something about looking up sourcemaps from inherited contracts is broken at some point. Trying my best to figure out if that's loading the sources when building the debugger or when looking up the pc in the map.

@emo-eth
Copy link
Contributor Author

emo-eth commented Feb 9, 2024

I've located the issue.

ContractSources is a mapping of name -> id -> (source code, bytecode)

In src_map, the source for the contract is looked up by name. Since this may return multiple contracts with the same name, the entries are iterated over and the SourceElement's index is compared to the file_id of the current contract source. If they match, the source code is returned.

The problem is that this will never return source code for inherited contracts, because it is only loading source code for (contracts with the same name as) the contract being invoked; if the SourceElement points to a different index (aka file_id), it will never match any of the contract sources loaded from ContractSources.

ContractSources should maintain an index both of name -> id -> (source, bytecode) and id -> (source, bytecode) for looking up cross-source sourcemaps.

@mmsaki
Copy link

mmsaki commented Jun 27, 2024

@emo-eth I having this same issue where the contract source is not loaded. I am reading your comments here but it doesn't mention anything about how to resolve it. Can you share how to get the contract to be loaded on the debug panel?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-bug Type: bug
Projects
No open projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants