foundry
foundry copied to clipboard
meta(debugger): tracking issue for debugger improvements
Meta
Decoding/display
- [ ] Guidance on how to debug failed tests in the CLI output
- [ ] Visual clues that a precompile is being called (requires more thought, see #916)
- [ ] Showing current values of variables (https://github.com/gakonst/foundry/issues/410)
- [ ] Allow toggling of individual panes for flexible layout
Bugs
- [ ] https://github.com/foundry-rs/foundry/issues/5435
Quality of life
- [ ] If the debugger is started with no arguments, it would be cool if we could display a list of contracts (further broken down by functions) that the user can interactively select
Control flow
- [ ] Breakpoints
Capabilities
- [ ] Debugging of constructors
- [ ] Debugging calls to external contracts (i.e., no local contract is deployed, but a fake call to a live contract is debugged)
- [ ] Storage view
UI
- [ ] https://github.com/foundry-rs/foundry/issues/8256
Big ticket items
- [ ] Have an actual interactive debugger. We currently record what happens and play it back to the user, but this can lead to situations where we run out of memory
Idea for an interactive debugger: some Debugger struct that handles state/displays UI. Messages are passed between the Debugger and the debug inspector. Contracts are identified on the fly when the EVM switches context using any number of identifiers
@onbjerg supose I want to debug the function in the test below called symbol(). Using the forge test --debug symbol I have to jump a looootttt until I find it. What would be needed to jump directly to my function using the debugger ? I have the impression that using the function signature 0x95d89b41 as an input we could just search it and jump the counter to there. Makes sense ? Is there anyone writing it ?
(I am using the foundry-huff)
function testSymbol() public {
string memory r = token.symbol();
string memory n = 'JHX';
assertEq(n,r);
}
#define macro SYMBOL() = takes (0) returns (0) {
0x20 0x00 mstore
[META_SYMBOL_LENGTH] 0x20 mstore
[META_SYMBOL] 0x40 mstore
0x60 0x00 return
}
@henry-hz You can use vm.breakpoint
To add to this, it'll be awesome to have a vim-styled "command mode" that supercedes navigation shortcuts. Though it'll be nice to have a full-blown lua scripting engine to interface with during debugging, it'll be a huge improvement to simply have basic commands;
:mem <pos>,mems <slot>given either a slot position or index, print or snap to and highlight that specific memory location:store <addr>similar operations to inspect specific storage slots:continue <pc>- fast-forward until execution reaches a specific pc on the current contract. More ergonomic than usingvm.breakpointimo as you don't need to rebuild contracts to add new breakpoints.- A way to scroll the source map display so users can easily see the pc that maps to a given line number in code.
A command-based debug flow would be a good way to introduce feature experiments without cluttering the existing interface.
@Inphi Agree, but why would we need to write a lua interface if it can be integrated in the Tui directly ?
Though we could use / to search for opcode
@iFrostizz Lua interface is to write (inline) scripts to automate certain debug flows. Kind of like gdb scripts.
From https://github.com/foundry-rs/foundry/issues/4440#issue-1601444539
The debugger should be interactive to allow for collapsing traces, show/hiding more information, etc. Tenderly debugger/trace UX is very nice IMO so is a good source of inspiration. More info coming soon, need to link existing issues here
(...)
For example, you can imagine the debugger config looking something like this (made up type names within the Options):
struct DebuggerConfig {
trace: Option<CallTrace>,
opcodes: Option<Vec<Opcodes>>,
memory_states: Option<Vec<Memory>>,
stack_states: Option<Vec<Stack>>,
srcmap: Option<SrcMap>,
}
where "trace view" simply has None everywhere except for trace, while debugger mode may have everything enabled. Users could toggle each config option on/off in the debugger UI.
From #5553:
- Making it smarter about where solidity structs are laid out and labelling them with variable names
- visual storage/memory explorer with struct/variable knowledge
- calling convention/ABI.encode awareness
- get better at not losing where it is with weird assembly/reentrancy
- It would be nice to have a pane to look at the storage of the current contract. Since storage can be large, it would be nice to query values by the slot number.
- We also have TSTORE now, so we could also have a transient storage pane.
- For some reason setting breakpoints in the source code didn't work for me, breakpoints in tests work fine.
- Any way to set a breakpoint within an assembly block? Probably not possible, but If the assembly block is large, then you have to scroll through a lot of opcodes to reach the point you care about.
- Also ability to query words at different calldata and memory offsets without scrolling through the relevant panes. It would be amazing UX if I could type a command like - :0x20 --memory/calldata/storage/transient And just get the value at that slot.