A debugger for the Tezos smart contract language Michelson.
Implemented in OCaml.
Hooks straight into the Octez Michelson interpreter.
Wraps everything up in the Debug Adapter Protocol.
Please see the Developer Setup below to get started.
Many thanks to the Tezos Foundation who are funding this work.
If you would also like to get involved through sponsorship please see here.
If you just want to chat please reach out on Twitter @karoshibee or LinkedIn.
The Tezos Weevil is currently under heavy development so to play along please check out the source code and build locally.
Developed/Tested on Ubuntu 22.04.1 LTS with opam version 2.1.2, you will need to make sure that ocaml-base-compiler.4.14.0 is available:
$ opam switch list-available | grep base-compiler | grep Official
ocaml-base-compiler 4.12.0 Official release 4.12.0
ocaml-base-compiler 4.12.1 Official release 4.12.1
ocaml-base-compiler 4.13.0 Official release 4.13.0
ocaml-base-compiler 4.13.1 Official release 4.13.1
>>> ocaml-base-compiler 4.14.0 Official release 4.14.0 <<<
$ git checkout https://github.com/karoshibee/weevil.git
$ cd weevil/
$ opam switch create . ocaml-base-compiler.4.14.0
Package weevil does not exist, create as a NEW package? [Y/n] Y
...lots of packages get installed
The dune build tool should now be available, I usually leave it running in watch mode (from project root):
$ dune build -w
To run locally in Emacs you will need to do three things:
In a local shell run
$ dune exec -- weevil adapter -v -v
This should set the adapter service running and listening to connections on the default port 9000.
Step 2 - load the dap-weevil extension to Emacs dap-mode
In Emacs open the dap-weevil elisp file and evaluate the elisp
M-x eval-buffer
This should make available five example dap-debug sessions that can be run/debugged with the weevil.
These five setups correspond to the five examples found in the weevil source which are taken from the five examples used in the opentezos website.
M-x dap-debug
It should show you the five debug sessions from the previous step, choose the one you want to debug.
The debug session should start and you should see Emacs connecting with the adapter.
To step into the Michelson code do
M-x dap-next
The example code file should be presented (if you aren't already viewing it in a buffer) with the current line and cursor point highlighted.
To see a standard debugging window setup do
M-x dap-ui-show-many-windows
On the right-hand side you should be able to drill down into the Michelson stack & gas along with the input parameter values and initial storage.
Repeated use of
M-x dap-next
will alllow you to continue to step through the Michelson code one instruction at a time.
To disconnect use
M-x dap-disconnect
NOTE currently that is all the UI instructions that the weevil will respond to.
In Emacs you will need to run (after doing the three steps above)
M-x dap-debug-edit-template
and choose one of the five setups to copy - it doesn't matter which one.
Edit the script_filename
, storage
and parameter
string fields to the filename, storage and input parameter values you want.
Dont forget to also change the name
field and have it register under that same new name.
Now when you next run M-x dap-debug
you should see that new setup as one of the choices to run.
Currently we recommend running the adapter with the -v -v
logging level (debug) to have full visibility of the message passing and sequencing of events.
Note also that by default the backend debugger service logs to a file called ROOT/weevil_mdb.log
.
Please look in there for extra information if something is not running as expected. It is possible that some errors in the backend do not get propagated back to the adapter (and on to the UI). Please raise an issue if this is the case.
To run the all the tests simply do (from project root):
$ dune runtest -f
Tests currently consist of Alcotest unit/qcheck tests, expect tests and cram tests.
The qcheck tests can take some time to run through so to just run the quick tests do
$ ALCOTEST_QUICK_TESTS=1 dune runtest -f
Coverage statistics can be determined using the bisect ppx tool.
As described in the link, you can perform a full test with statistics gathering using:
# make a dir to keep the bisect_ppx output
$ mkdir _bisect
# remove previous data
$ find . -name '*.coverage' | xargs rm -f
# run tests with instrumentation
$ BISECT_FILE=$PWD/_bisect/bisect dune runtest --force --instrument-with bisect_ppx
The BISECT_FILE env var is used to ensure that the cram test sandboxing does not clean up (delete) the coverage data for those same cram tests. One can then look at a summary:
$ bisect-ppx-report summary --per-file --coverage-path $PWD/_bisect
or generate a full report:
$ bisect-ppx-report html --tree --coverage-path $PWD/_bisect
The html bundle is written to the _coverage directory by default; the contents of which can be served with a simple web server a la:
$ python -m http.server --directory _coverage/
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
This html report can then be viewed with your web browser at http://localhost:8000
WARN under heavy development - it is recommended to follow Developer Setup above.
However an early preview version is available on opam; just do the usual
$ opam install weevil
With this version you can run the weevil
command to have a preview of the functionality, for example you can run the stepper
directly as a CLI tool:
$ weevil_mdb_016 stepper -v -v --headless --storage '0' --parameter '(Pair 7 5)' --entrypoint 'default' open_tezos_example1_looping.tz
It will pause at the first Michelson instruction, to step just press <return>
.
To obtain the full functionality please use the Developer Setup.
-
Notes on messaging including how to use the
weevil dap-gen
tool to auto-generate OCaml code for all the DAP message types, -
Notes on the
weevil
Michelson stepper, -
Notes on the
weevil
debug adapter.
Pretty early-stage; here's a demo of an early prototype Emacs integration: