Skip to content

feat: add internal spec for debug-info - #16780

Merged
cameel merged 1 commit into
argotorg:developfrom
walnuthq:feature/internal-spec
Aug 19, 2026
Merged

feat: add internal spec for debug-info#16780
cameel merged 1 commit into
argotorg:developfrom
walnuthq:feature/internal-spec

Conversation

@djolertrk

@djolertrk djolertrk commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

This introduces the compiler-side model for carrying Solidity semantic debug info through the Yul pipeline, including AST-ID based reattachment across Yul reparse.

See docs/internals/ethdebug_internal_debug_info.rst for more detailed explanation of the design.

@djolertrk
djolertrk marked this pull request as draft June 5, 2026 15:50
@djolertrk

Copy link
Copy Markdown
Contributor Author

cc @nikola-matic @clonker

@nikola-matic nikola-matic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you fix the build (the comment I left below should do it), and then can you drop a solc-bench in here.

Comment thread liblangutil/SemanticDebugData.h Outdated
@djolertrk

Copy link
Copy Markdown
Contributor Author

@nikola-matic I fixed the build and here is the solc-bench output:

Benchmark          Metric         ir-ethdebug           ir                   Δ%        winner
-----------------  -------------  --------------------  -------------------  --------  ------
prb-math-4.1.1     cpu_time       12.1321s ± 0.4704s    10.0406s ± 0.3165s   +20.83%   ir
                   creation_size  592,270 ± 0           592,270 ± 0          0.0%      tie
                   peak_rss       2044080 ± 96536 MiB   1295600 ± 52003 MiB  +57.77%   ir
                   runtime_size   589,640 ± 0           589,640 ± 0          0.0%      tie
                   wall_time      12.8027s ± 0.6464s    10.4773s ± 0.4362s   +22.2%    ir
                   ethdebug_size  44.80 MiB ± 0.00 MiB  n/a                  N/A       n/a

forge-std-1.16.1   cpu_time       11.8554s ± 0.2979s    10.2449s ± 0.1482s   +15.72%   ir
                   creation_size  725,280 ± 0           725,280 ± 0          0.0%      tie
                   peak_rss       1554816 ± 70351 MiB   796144 ± 9474 MiB    +95.29%   ir
                   runtime_size   698,851 ± 0           698,851 ± 0          0.0%      tie
                   wall_time      12.1417s ± 0.3452s    10.4575s ± 0.1829s   +16.1%    ir
                   ethdebug_size  44.94 MiB ± 0.00 MiB  n/a                  N/A       n/a

morpho-blue-1.0.0  cpu_time       16.3965s ± 0.7634s    14.7222s ± 1.0004s   +11.37%   ~noise
                   creation_size  1,261,421 ± 0         1,261,421 ± 0        0.0%      tie
                   peak_rss       1824912 ± 50816 MiB   921792 ± 34683 MiB   +97.97%   ir
                   runtime_size   1,251,246 ± 0         1,251,246 ± 0        0.0%      tie
                   wall_time      16.9356s ± 0.9110s    15.0786s ± 1.1852s   +12.32%   ~noise
                   ethdebug_size  57.38 MiB ± 0.00 MiB  n/a                  N/A       n/a

solmate-6          cpu_time       6.9523s ± 0.1573s     6.0532s ± 0.3605s    +14.85%   ir
                   creation_size  540,758 ± 0           540,758 ± 0          0.0%      tie
                   peak_rss       919888 ± 33125 MiB    379440 ± 18556 MiB   +142.43%  ir
                   runtime_size   523,577 ± 0           523,577 ± 0          0.0%      tie
                   wall_time      7.1106s ± 0.1848s     6.2070s ± 0.4427s    +14.56%   ir
                   ethdebug_size  30.92 MiB ± 0.00 MiB  n/a                  N/A       n/a

Thank you!

@djolertrk
djolertrk force-pushed the feature/internal-spec branch 2 times, most recently from 9fd16e7 to d08f715 Compare June 11, 2026 07:21
@djolertrk
djolertrk marked this pull request as ready for review June 11, 2026 07:21
@cameel
cameel self-requested a review June 29, 2026 13:35
Comment thread liblangutil/SemanticDebugData.h Outdated
Comment thread libsolidity/interface/CompilerStack.cpp
Comment thread libyul/YulStack.cpp Outdated
Comment thread test/libsolidity/SemanticDebugData.cpp Outdated

@cameel cameel left a comment

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.

Here's a bunch of remarks from the first reading through the spec. I'm not done yet so I'll likely have more later.

Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
@djolertrk
djolertrk force-pushed the feature/internal-spec branch 2 times, most recently from 822d2e3 to a8785c2 Compare July 23, 2026 08:31
Comment thread liblangutil/SemanticDebugDataSerialization.cpp Outdated
Comment thread liblangutil/SemanticDebugDataSerialization.cpp Outdated
@djolertrk
djolertrk force-pushed the feature/internal-spec branch from 1af126d to 5e4b1de Compare July 31, 2026 14:08

@cameel cameel left a comment

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.

Sorry for the delay. Here's another batch of remarks. The spec is much better now, containing a lot of detail that was missing before. I think there are still some holes in it though.

Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
@djolertrk
djolertrk force-pushed the feature/internal-spec branch 2 times, most recently from 37b9141 to 1460456 Compare August 6, 2026 08:56
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
@djolertrk
djolertrk force-pushed the feature/internal-spec branch 3 times, most recently from 605588c to c1988bb Compare August 12, 2026 13:40
@cameel

cameel commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Some remarks regarding the scope of this implementation spec.

Back when we were preparing the implementation plan for ethdebug I expected that this document would end up being much more detailed, and already free us from most design choices upfront. Then you'd be able to focus on implementation without major blockers. That was a bit too ambitious, so I'm fine with just focusing on fleshing out the Yul sidecar format here. Once that's done, we can merge the PR. I'll post my more specific comments in a moment.

As for the final form of the spec/docs, we can move towards that in further PRs and in the meantime you can work on implementing the bits that are already documented and agreed on. More concretely, here's what I have in mind for the full scope:

  1. User-facing documentation:
    1. Ethdebug in compiler's interface (CLI/Standard JSON)
    2. Structure of ethdebug outputs (can just refer to ethdebug schemas, but should describe any extra structure we add to it)
    3. Yul debug info sidecar format.
    4. Yul debug info constraints. I.e. what is allowed, where, what to do to have it accepted and preserved correctly. From the point of view of someone writing a language that compiles to Yul.
  2. Documentation of compiler internals (aimed at solc developers/contributors):
    1. How each language type maps to the type schema.
    2. How we decide where to place @ast-ids and what to include in the sidecar.
    3. How we assign initial locations to variables and what pointers look like for each type/location.
    4. What transformations are applied to the debug data by each optimizer step.
    5. How we pass debug data through the Yul->EVM transform
    6. How the debug data that ends up in AssemblyItems maps to the final ethdebug output

For the user-facing docs, I'd create a dedicated page for debug info (not just ethdebug, everything related to how debug info works in Solidity and Yul).

For implementation docs we do not have a good place yet, so let's create one. I really don't see it as a part of the current topic hierarchy, it's too low level and meant for a different audience, so my suggestion is to create a separate TOC tree on a new page that's not reachable from the current TOC. We can later think how to expose it, but just being able to get there if you know the link would be enough for now.

To be clear - you don't have to do that in this PR yet. The current document mixes the two categories and that's fine for now. I see it more as an initial draft. Please just remove the page from the TOC and make it an orphan so that it's not exposed to users yet.

You already have a lot of this info, but in the final form I'd like to see more detail. Especially on the implementation doc side - the idea was for this to be a high-level description of what you're going to do in the PRs. And I'm mostly interested in reviewing that and leaving smaller details up to you and @nikola-matic.

Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated

@cameel cameel left a comment

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.

Here's the final batch of substantial comments about the content. Once we get through these, we're done with the hard stuff.

I'll also have a few more trivial ones (naming, formattiong), but those should be pretty easy to address. I intentionally left them for the end.

Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated

@cameel cameel left a comment

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.

And here are the final nitpicks.

Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
Comment thread docs/internals/ethdebug_internal_metadata.rst Outdated
@djolertrk
djolertrk force-pushed the feature/internal-spec branch from c1988bb to 1e39e2c Compare August 14, 2026 13:59
@djolertrk

Copy link
Copy Markdown
Contributor Author

Some remarks regarding the scope of this implementation spec.

Back when we were preparing the implementation plan for ethdebug I expected that this document would end up being much more detailed, and already free us from most design choices upfront. Then you'd be able to focus on implementation without major blockers. That was a bit too ambitious, so I'm fine with just focusing on fleshing out the Yul sidecar format here. Once that's done, we can merge the PR. I'll post my more specific comments in a moment.

As for the final form of the spec/docs, we can move towards that in further PRs and in the meantime you can work on implementing the bits that are already documented and agreed on. More concretely, here's what I have in mind for the full scope:

  1. User-facing documentation:

    1. Ethdebug in compiler's interface (CLI/Standard JSON)
    2. Structure of ethdebug outputs (can just refer to ethdebug schemas, but should describe any extra structure we add to it)
    3. Yul debug info sidecar format.
    4. Yul debug info constraints. I.e. what is allowed, where, what to do to have it accepted and preserved correctly. From the point of view of someone writing a language that compiles to Yul.
  2. Documentation of compiler internals (aimed at solc developers/contributors):

    1. How each language type maps to the type schema.
    2. How we decide where to place @ast-ids and what to include in the sidecar.
    3. How we assign initial locations to variables and what pointers look like for each type/location.
    4. What transformations are applied to the debug data by each optimizer step.
    5. How we pass debug data through the Yul->EVM transform
    6. How the debug data that ends up in AssemblyItems maps to the final ethdebug output

I strongly believe that this spec is a live thing, and that changing it in future is inevitable. So, yeah, I do agree that it can be our final goal!

For the user-facing docs, I'd create a dedicated page for debug info (not just ethdebug, everything related to how debug info works in Solidity and Yul).

For implementation docs we do not have a good place yet, so let's create one. I really don't see it as a part of the current topic hierarchy, it's too low level and meant for a different audience, so my suggestion is to create a separate TOC tree on a new page that's not reachable from the current TOC. We can later think how to expose it, but just being able to get there if you know the link would be enough for now.

To be clear - you don't have to do that in this PR yet. The current document mixes the two categories and that's fine for now. I see it more as an initial draft. Please just remove the page from the TOC and make it an orphan so that it's not exposed to users yet.

You already have a lot of this info, but in the final form I'd like to see more detail. Especially on the implementation doc side - the idea was for this to be a high-level description of what you're going to do in the PRs. And I'm mostly interested in reviewing that and leaving smaller details up to you and @nikola-matic.

Yes, we are on the same page!

@djolertrk

Copy link
Copy Markdown
Contributor Author

@cameel thank you!

@cameel cameel left a comment

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.

Here's another batch of comments. At this point I think we have all the major issues in the format resolved so it's mostly about small technical details and clarifications.

Please also recheck my earlier, still unresolved comment threads. It seems that there are 2 or 3 at the beginning that you missed.

Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
``SSATransform`` and ``Rematerialiser`` cannot be expressed as whole-scope updates, because the pointer or phase changes between program points.
They must emit variable updates instead - see `Variable Updates`_.
Substituting a variable use by its defining expression can leave the variable itself unused and later pruned.
The value is then still recoverable by evaluating that expression, so its phase becomes ``Computed`` rather than ``OptimizedOut``.

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.

So just to be clear: we don't provide any detailed information on how to recover a value of a "computed" variable. The debugger has to figure it out on its own?

Does the final ethdebug output actually contain any breadcrumbs for the debugger? nativeLocation of the expression I guess? Or some range of instructions in the bytecode that compute it?

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.

Well, we must talk about this on the ethdebug call. There is no recipe, the debugger will show a computed value as unavailable, same as optimizedOut atm. The distinction is about truthfulness: recomputable in principle vs. definitely gone. And no real breadcrumbs to promise either, instruction-to-source mapping exists anyway, but re-evaluating the source expression is debugger heuristics, not something the format guarantees. The proper fix would be value expressions in the DWARF sense (DW_OP_stack_value), but ethdebug pointers only describe regions today, so that's an upstream schema extension. Clarified the computed row and added a note about exactly this.

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.

ok. Definitely sounds like we should discuss it on the call. Can you also file an upstream issue about it? This would give us a place to discuss it async.

Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
Comment thread docs/internals/ethdebug_internal_debug_info.rst Outdated
cameel
cameel previously approved these changes Aug 19, 2026

@cameel cameel left a comment

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.

There's one minor remark left (#16780 (comment)).

Other than that, this looks ready. Great work!

The last thing is to clean up the commits (fine to squash into one, unless you see the need for more structure here) and then we can proceed with merging.

This introduces the compiler-side model for carrying Solidity
semantic debug info through the Yul pipeline, including AST-ID
based reattachment across Yul reparse.

See docs/internals/ethdebug_internal_debug_info.rst for more
detailed explanation of the design.
@djolertrk
djolertrk force-pushed the feature/internal-spec branch from 1a018af to 064b70c Compare August 19, 2026 19:08
@djolertrk

Copy link
Copy Markdown
Contributor Author

There's one minor remark left (#16780 (comment)).

Other than that, this looks ready. Great work!

The last thing is to clean up the commits (fine to squash into one, unless you see the need for more structure here) and then we can proceed with merging.

Thanks a lot for your comments!

@cameel cameel left a comment

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.

ok then, let's ship it :)

@cameel
cameel enabled auto-merge August 19, 2026 19:11
@cameel
cameel merged commit 497166e into argotorg:develop Aug 19, 2026
83 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants