Skip to main content

For compiler authors

You're building a compiler or toolchain that produces EVM bytecode. Here's how to emit ethdebug/format data so debuggers can provide rich debugging experiences for your users.

What you need to emit

ethdebug/format defines several kinds of debug information:

  • Type information — Describe the structure of data in your language (integers, structs, arrays, mappings)
  • Pointer information — Describe where variables are stored at runtime, including dynamic locations computed from other values
  • Program information — Describe what's in scope at each bytecode instruction, mapping bytecode back to source code
  • Info schema — Bundle everything together with source files and compilation metadata

Quick example: describing a type

Here's how to describe a simple uint256:

{
"kind": "uint",
"bits": 256
}

A storage mapping from addresses to balances:

An address → uint256 mappingSchema:ethdebug/format/type/complex/mapping
{
"kind": "mapping",
"contains": {
"key": { "type": { "kind": "address" } },
"value": { "type": { "kind": "uint", "bits": 256 } }
}
}

Quick example: describing a storage variable

A pointer tells debuggers where to find a variable's value. For a uint256 at storage slot 0:

{
"location": "storage",
"slot": "0x0",
"length": 32
}

For a dynamic array where the length is at slot 2 and elements start at keccak256(2):

{
"group": [
{ "name": "array-length", "location": "storage", "slot": "0x2" },
{
"list": {
"count": { "$read": "array-length" },
"each": "i",
"is": {
"location": "storage",
"slot": {
"$sum": [{ "$keccak256": [{ "$wordsized": "0x2" }] }, "i"]
}
}
}
}
]
}

Integration approach

Most compilers can add ethdebug/format support incrementally:

  1. Start with types — Emit type definitions for your language's data structures. This can be a straightforward starting point.
  2. Add storage pointers — Describe where storage variables live. Many variables have static locations.
  3. Add memory/stack pointers — Describe temporary values. These often require tracking allocation during code generation.
  4. Add program information — Emit source mappings and scope information. This typically requires the most compiler changes.

Go deeper

Compiler implementation guide

Detailed guidance on emitting ethdebug/format from your compiler.

Specification

Formal schema definitions for all ethdebug/format structures.

Explore by topic

  • Types — Full documentation on type definitions
  • Pointers — Full documentation on pointer definitions
  • Programs — Full documentation on program annotations
  • Info schema — Full documentation on bundling debug data
  • BUG Playground — See a working compiler that emits ethdebug/format