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

EVM opcode: breakpoint #201

Closed
axic opened this issue Feb 2, 2017 · 21 comments
Closed

EVM opcode: breakpoint #201

axic opened this issue Feb 2, 2017 · 21 comments
Labels

Comments

@axic
Copy link
Member

axic commented Feb 2, 2017

Motivation

To speed up debugging, if a breakpoint is expected there is no need to step through execution, but can safely stop at the breakpoint.

Specification

A new opcode, BREAKPOINT is introduced at 0xfd.

Option 1:

A virtual machine if run in debugging mode, should stop execution when encountering this instruction, otherwise it should ignore it.

Option 2:

It stays as an invalid instruction in a deployed contract, but special debugging EVM implementations are allowed to support it.

Alternatively, another good name is DEBUG.

@Arachnid
Copy link
Contributor

Arachnid commented Feb 2, 2017

Can't debuggers set breakpoints using external information? This method would require changing the code every time you want to add or remove breakpoints.

@gcolvin
Copy link
Contributor

gcolvin commented Feb 21, 2017

The C++ VM has hook for a callback function that can be and I think is used for debugging. @yann300 ?

@yann300
Copy link

yann300 commented Feb 22, 2017

Yes. Though that would mean to readd the JavaScript interpreter I guess...

@gcolvin
Copy link
Contributor

gcolvin commented Feb 25, 2017

@yann300 I don't really understand, as the hook must already be used by any debugger that wants to single-step, inspect stack and memory, etc. The hook gets called for every instruction executed, so it can stop when the desired program counter is reached. But I do get that performance takes a hit. If we do go with the breakpoint instruction there would need to be a way to call into the running VM to modify the code, and probably a way to get the other information the hook provides. Just stopping doesn't help if you can't inspect the state of the program.

@yann300
Copy link

yann300 commented Feb 27, 2017

Calling the running VM to modify the code on the fly sounds interesting.
When the user is is debug session, the bytecode could be updated as the user is writing new solidity code that is about to be executed... (not sure if it completely doable).
As remix is in JavaScript that would mean to add a JavaScript interpreter in a c++ code that could call JavaScript callback right? or maybe I misunderstood something....

@gcolvin
Copy link
Contributor

gcolvin commented Feb 28, 2017

I only meant modifying a single opcode with this new BREAKPOINT opcode.

@yann300
Copy link

yann300 commented Feb 28, 2017

yes i know, I was just wondering if we could also update the bytecode as the user is writting. Some IDEs do that.

@nmushegian
Copy link

A general principle of ethereum and blockchains is if it can be done off-chain, do it off chain.

@kumavis
Copy link
Member

kumavis commented Jul 14, 2017

0xfd is claimed by revert

@GNSPS
Copy link

GNSPS commented Jul 17, 2017

I really like the idea of having a breakpoint opcode. I feel that option 2 kind of defeats the purpose of standardizing this though, I would go with 1.

Would it make sense to mimic x86 arch and have an interrupt opcode with a single byte param?

The VM, if run in debugging mode, would then have the opportunity to have stored routines given different interrupt values. (And we could have a single-byte version for the breakpoint interrupt much like INT 3 in x86.

@insipx
Copy link

insipx commented Nov 11, 2017

I like the idea of mimic-ing x86 functionality along with UNIX Opcodes. On UNIX, the process of breakpoints looks something like:

Create Breakpoint

    Compute location of the break point
    Read byte that was there and save it.
    Put 0xCC byte there (int3 opcode). If program is ptraced, executing int3 will freeze it.

disabling Breakpoints:

    Disable breakpoint (write back old instruction)
    Run single step (PTRACE_SINGLESTEP)
    Enable breakpoint (write int3)
    Continue (PTRACE_CONT)

It could look similar in EVM too.

@gcolvin
Copy link
Contributor

gcolvin commented Nov 11, 2017

It might be more useful to consider something more general like the Java Debug Wire Protocol. The debugger asks the VM to set a breakpoint, single step, or whatever and it's up to the VM to make it happen however it likes.

@insipx
Copy link

insipx commented Nov 11, 2017

@gcolvin Huhm, didn't think of that. Definitely a potential solution, but I worry about it's extendability. Would this be more of a solidity feature, or can it be extended to apply to other languages (IE: Viper)? I'm not totally familiar with the Java Debug Wire Protocol. Would it require making changes to the VM for every language that is to be debugged with?

I think the con of doing it the UNIX-way would be the potential need to implement a compile option for debug symbols in order to be able to step-over and into solidity code rather than the underlying assembly. However, once an interface is created, it may be easier to create debug symbols for other languages rather than modify an interface similar to the Java Debug Wire Protocol.

@gcolvin
Copy link
Contributor

gcolvin commented Nov 11, 2017

It's not a language feature, it's a wire protocol that all JVMs have to implement. It could be optional if we wanted. That way any Java debugger can be used for either VM. Another advantage is that debuggers (Eclipse, JSwat, etc.) aren't linked to the VM, but connect via a socket. It's stood up to years of use and extension by now.

@gcolvin
Copy link
Contributor

gcolvin commented Nov 11, 2017

So yes, a protocol like that would be language and VM agnostic. It would even be possible for an EVM to pretend to be a JVM and use the actual JDWP for the purposes of debugging. We did that for PL/SQL at Oracle. Lining up source and bytecode might be an issue - the Java class file format takes care of that and we don't. At worst, the tool that created the code you are debugging could keep of that for the code it knows about, and perhaps disassemble other code if you don't want to work at the bytecode level.

@insipx
Copy link

insipx commented Nov 12, 2017

@gcolvin Did some digging on this topic, and actually the functionality of mapping the bytecode to sourcecode may already exist, taken from the docs for solidity compiler:

Furthermore, the compiler can also generate a mapping from the bytecode to the range in the source code that generated the instruction. This is again important for static analysis tools that operate on bytecode level and for displaying the current position in the source code inside a debugger or for breakpoint handling.

Both kinds of source mappings use integer identifiers to refer to source files. These are regular array indices into a list of source files usually called "sourceList", which is part of the combined-json and the output of the json / npm compiler.

The source mappings inside the AST use the following notation:

s:l:f

Where s is the byte-offset to the start of the range in the source file, l is the length of the source range in bytes and f is the source index mentioned above.

The encoding in the source mapping for the bytecode is more complicated: It is a list of s:l:f:j separated by ;. Each of these elements corresponds to an instruction, i.e. you cannot use the byte offset but have to use the instruction offset (push instructions are longer than a single byte). The fields s, l and f are as above and j can be either i, o or - signifying whether a jump instruction goes into a function, returns from a function or is a regular jump as part of e.g. a loop.

@gcolvin
Copy link
Contributor

gcolvin commented Nov 12, 2017

Does this mapping get stored on the blockchain?

@insipx
Copy link

insipx commented Nov 12, 2017

It does not, It's just a compiler option used on solidity code that outputs to stdout.

@gcolvin
Copy link
Contributor

gcolvin commented Nov 12, 2017

OK. Not so nice as what Java provides so far as debugging arbitrary code on the blockchain, but still very good for development.

@github-actions
Copy link

github-actions bot commented Jan 2, 2022

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Jan 2, 2022
@github-actions
Copy link

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants