Inspired by #16229 (comment).
Abstract
The way ethdebug outputs and settings were implemented in #15289 goes our conventions and is inconsistent with how these typically work on solc. They have unnecessary dependencies and are named in a way that neither is intuitive nor follows the spec. They are also not as granular as existing outputs. We should correct that while the feature is still experimental and can be modified without backwards-compatibility concerns.
Specification
Outputs
Output selection (Standard JSON):
- Global
ethdebug.resources: the ethdebug/format/info/resources schema. Requires only analysis.
ethdebug.compilation: the compilation key from the ethdebug/format/info/resources schema. No requirements.
- Per-contract
evm.bytecode.ethdebug: ethdebug/format/program schema for the creation bytecode of the contract. Requires compilation to bytecode.
evm.deployedBytecode.ethdebug: ethdebug/format/program schema for the deployed bytecode of the contract. Requires compilation to bytecode.
We currently do not support global outputs in Standard JSON. A backwards-compatible way to add them would be to both request and return them via */* (e.g. {"*": {"*": ["ethdebug.resources"]}}). Global outputs requested for specific files/contracts should be ignored.
Ethdebug outputs should not be selectable using *. We do not include experimental outputs in it and it is scheduled to be removed eventually (#16462).
Output selection (CLI):
--ethdebug-resources: equivalent to ethdebug.resources in Standard JSON.
--ethdebug-compilation: equivalent to ethdebug.compilation in Standard JSON.
--ethdebug-program: equivalent to evm.bytecode.ethdebug for all contracts in Standard JSON.
--ethdebug-program-runtime: equivalent to evm.deployedBytecode.ethdebug for all contracts in Standard JSON.
Different outputs depend on different stages of the pipeline. For example all we need to produce the resources schema is the AST, which requires only analysis. And the compilation schema can be produced as soon as the settings have been processed. As with existing outputs, requesting the ethdebug ones should automatically enable the required pipeline stages.
Note that the compiler does not reproduce the ethdebug/format/info schema. Most of the information is already contained in the outputs listed above and they can be easily combined into this schema by any tool that needs it.
Settings
Existing conventions for debug info settings
--debug-info/settings.debug.debugInfo setting controls how debug information is lowered through the pipeline. The overall principle is that this information is passed explicitly through source/AST. The user should get the same debug info at the end of the pipeline no matter whether the compilation was done in one go, or whether Yul/evmasm was exported and then fed back to the compiler.
In Yul this is done through comments with @ annotations. In evmasm the debug info is a part of AssemblyItem.
Currently there are 3 bits of debug info we can produce:
@use-src annotation. Lists Solidity input files that the Yul output was produced from and assigns them IDs.
- Always present.
- When parsing a Yul file and this annotation is missing, the compiler assumes that there is no debug info in the file.
@src annotation. Specifies the source location in the Solidity input file that the instruction following it was produced from.
- Enabled with
--debug-info location.
- The annotation may also include a code snippet corresponding to that original location. This is enabled with
--debug-info location,snippet.
@ast-id annotation. The AST ID of the original Solidity element that the following Yul element was produced from.
- Enabled with
--debug-info ast-id.
- Currently solc emits it only for functions and getters.
These elements should be mostly independent, but when they are not (like in case of location and snippet), requesting one without its dependency is an error.
Debug info output should degrade gracefully. For example, if the @src annotation is missing in Yul we simply do not include it in the evmasm output. We still include any other requested debug info we have.
Debug info setting for ethdebug
Now we're adding a new bit of info: ethdebug. The exact set of annotations is still not firmly decided, but so far initial PRs were using the @debug.set annotation with a bit of JSON. This is completely separate from other existing annotations and should not require any of them. Should also not depend on any outputs.
Discrepancies with implementation as of 0.8.33
- Outputs are not as granular and their names do not map to parts of the spec
- The global
ethdebug.resources and ethdebug.compilation outputs:
- Cannot be separately requested and are both automatically included when
evm.bytecode.ethdebug or evm.deployedBytecode.ethdebug is requested.
- Were hacked in under a separate top-level
ethdebug key in Standard JSON, outside of the usual output structure in sources.
- All ethdebug outputs currently require full compilation, even parts of the info schema.
- Requesting the
debugInfo: ["ethdebug"] in Standard JSON (but not on the CLI) is only possible if some specific outputs are requested.
Backwards Compatibility
Fully backwards-compatible because the feature is still experimental.
Inspired by #16229 (comment).
Abstract
The way ethdebug outputs and settings were implemented in #15289 goes our conventions and is inconsistent with how these typically work on solc. They have unnecessary dependencies and are named in a way that neither is intuitive nor follows the spec. They are also not as granular as existing outputs. We should correct that while the feature is still experimental and can be modified without backwards-compatibility concerns.
Specification
Outputs
Output selection (Standard JSON):
ethdebug.resources: theethdebug/format/info/resourcesschema. Requires only analysis.ethdebug.compilation: thecompilationkey from theethdebug/format/info/resourcesschema. No requirements.evm.bytecode.ethdebug:ethdebug/format/programschema for the creation bytecode of the contract. Requires compilation to bytecode.evm.deployedBytecode.ethdebug:ethdebug/format/programschema for the deployed bytecode of the contract. Requires compilation to bytecode.We currently do not support global outputs in Standard JSON. A backwards-compatible way to add them would be to both request and return them via
*/*(e.g.{"*": {"*": ["ethdebug.resources"]}}). Global outputs requested for specific files/contracts should be ignored.Ethdebug outputs should not be selectable using
*. We do not include experimental outputs in it and it is scheduled to be removed eventually (#16462).Output selection (CLI):
--ethdebug-resources: equivalent toethdebug.resourcesin Standard JSON.--ethdebug-compilation: equivalent toethdebug.compilationin Standard JSON.--ethdebug-program: equivalent toevm.bytecode.ethdebugfor all contracts in Standard JSON.--ethdebug-program-runtime: equivalent toevm.deployedBytecode.ethdebugfor all contracts in Standard JSON.Different outputs depend on different stages of the pipeline. For example all we need to produce the resources schema is the AST, which requires only analysis. And the compilation schema can be produced as soon as the settings have been processed. As with existing outputs, requesting the ethdebug ones should automatically enable the required pipeline stages.
Note that the compiler does not reproduce the
ethdebug/format/infoschema. Most of the information is already contained in the outputs listed above and they can be easily combined into this schema by any tool that needs it.Settings
Existing conventions for debug info settings
--debug-info/settings.debug.debugInfosetting controls how debug information is lowered through the pipeline. The overall principle is that this information is passed explicitly through source/AST. The user should get the same debug info at the end of the pipeline no matter whether the compilation was done in one go, or whether Yul/evmasm was exported and then fed back to the compiler.In Yul this is done through comments with
@annotations. In evmasm the debug info is a part ofAssemblyItem.Currently there are 3 bits of debug info we can produce:
@use-srcannotation. Lists Solidity input files that the Yul output was produced from and assigns them IDs.@srcannotation. Specifies the source location in the Solidity input file that the instruction following it was produced from.--debug-info location.--debug-info location,snippet.@ast-idannotation. The AST ID of the original Solidity element that the following Yul element was produced from.--debug-info ast-id.These elements should be mostly independent, but when they are not (like in case of
locationandsnippet), requesting one without its dependency is an error.Debug info output should degrade gracefully. For example, if the
@srcannotation is missing in Yul we simply do not include it in the evmasm output. We still include any other requested debug info we have.Debug info setting for ethdebug
Now we're adding a new bit of info:
ethdebug. The exact set of annotations is still not firmly decided, but so far initial PRs were using the@debug.setannotation with a bit of JSON. This is completely separate from other existing annotations and should not require any of them. Should also not depend on any outputs.Discrepancies with implementation as of 0.8.33
ethdebug.resourcesandethdebug.compilationoutputs:evm.bytecode.ethdebugorevm.deployedBytecode.ethdebugis requested.ethdebugkey in Standard JSON, outside of the usual output structure insources.debugInfo: ["ethdebug"]in Standard JSON (but not on the CLI) is only possible if some specific outputs are requested.Backwards Compatibility
Fully backwards-compatible because the feature is still experimental.