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

feat: add an interactive debugger to GnoVM #1563

Merged
merged 42 commits into from
May 14, 2024
Merged

Conversation

mvertes
Copy link
Contributor

@mvertes mvertes commented Jan 19, 2024

gno-debug

We provide here an embedded interactive debugger to let the user control and inspect its program at symbolic level, with the same features and commands as classical debuggers: gdb, lldb or delve.

The debugger is enabled by setting the -debug flag in gno run command, which loads the target program and immediately shows a debugger prompt on the console:

$ gno run -debug /tmp/my-program.gno
Welcome to the Gnovm debugger. Type 'help' for list of commands.
dbg>

Providing -debug-addr flag allows to start a remote debugging session, and not interfer with the program stdin and stdout. For example, in a first terminal:

$ gno run -debug-addr :4000 /tmp/my-program.gno
Waiting for debugger client to connect at :4000

And in a second terminal, using a netcat like nc(1):

$ nc localhost 4000
Welcome to the Gnovm debugger. Type 'help' for list of commands.
dbg>

The debugger works by intercepting each execution step at virtual machine level (each iteration within Machine.Run loop) to a callback, which in turns can provide a debugger command REPL or check if the execution can proceed to the next step, etc.

The general logic and structure is there. It is possible to continue, stepi, detach, print, stack, etc and get a general feedback of the user experience and the impact on the code.

Efforts are made to make this feature minimally intrusive in the actual VM, and not interfering when the debugger is not used.

It is planned shortly after this PR is integrated to add the capacity to attach to an already running program, and to taylor the data format for existing debugging environments such as VScode, etc, as demand arises.

Resolves gnolang/hackerspace#54

Contributors' checklist...
  • Added new tests, or not needed, or not feasible
  • Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory
  • Updated the official documentation or not needed
  • No breaking changes were made, or a BREAKING CHANGE: xxx message was included in the description
  • Added references to related issues and PRs
  • Provided any useful hints for running manual tests
  • Added new benchmarks to generated graphs, if any. More info here.

We provide here an embedded interactive debugger to let the user control
and inspect its program at symbolic level, with the same features and
commands as classical debuggers: gdb, lldb or delve.

The debugger is enabled by setting the `-debug` flag in `gno run`
command, which loads the target program and immediately shows a debugger
prompt on the console:

	$ gno run -debug /tmp/my-program.gno
	Welcome to the Gnovm debugger. Type 'help' for list of commands.
	dbg>

Providing `-debug-addr` flag allows to start a remote debugging session,
and not interfer with the program stdin and stdout.
For example, in a first terminal:

	$ gno run -debug-addr :4000 /tmp/my-program.gno
	Waiting for debugger client to connect at :4000

And in a second terminal, using a netcat like nc(1):

	$ nc localhost 4000
	Welcome to the Gnovm debugger. Type 'help' for list of commands.
	dbg>

The debugger works by intercepting each execution step at virtual
machine level (each iteration within `Machine.Run` loop) to a
callback, which in turns can provide a debugger command REPL or
check if the execution can proceed to the next step, etc.

This change request is still work-in-progress, as many debugger commands
are not ready yet. Nevertheless, the general logic and structure is
there. It is possible to `continue`, `stepi`, `detach`, etc and get
a general feedback of the user experience and the impact on the code.

Efforts are made to make this feature minimally intrusive in the actual
VM, and not interfering when the debugger is not used.

It is planned shortly after this PR is integrated to add the capacity
to attach to an already running program, and to taylor the data format
for existing debugging environments such as VScode, etc, as demand
arises.
@github-actions github-actions bot added the 📦 🤖 gnovm Issues or PRs gnovm related label Jan 19, 2024
@mvertes mvertes marked this pull request as draft January 19, 2024 14:06
@mvertes mvertes changed the title feat: and an interactive debugger to GnoVM feat: add an interactive debugger to GnoVM Jan 19, 2024
@mvertes mvertes marked this pull request as ready for review February 1, 2024 13:29
@zivkovicmilos zivkovicmilos self-requested a review February 1, 2024 16:51
@mvertes
Copy link
Contributor Author

mvertes commented Feb 2, 2024

I have found some issues when computing the stack from a non func block (like if or for body).

I also found some issues when printing a global var.

I would like also to set a test suite for the various debugger commands and in the various possible contexts such as the ones mentioned above. That requires a bit more work, maybe in a new PR (still pondering).

Copy link
Contributor

@harry-hov harry-hov left a comment

Choose a reason for hiding this comment

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

good to merge after fixing the path resolution and break command.

preapproving!

Copy link
Member

@zivkovicmilos zivkovicmilos left a comment

Choose a reason for hiding this comment

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

It is always a joy to read your code 💯

I've left a few comments, mostly questions to help me better understand the direction.
Thank you for implementing this 🙏

gnovm/pkg/gnolang/debugger.go Outdated Show resolved Hide resolved
gnovm/pkg/gnolang/debugger.go Show resolved Hide resolved
gnovm/pkg/gnolang/debugger.go Outdated Show resolved Hide resolved
gnovm/pkg/gnolang/debugger.go Show resolved Hide resolved
gnovm/pkg/gnolang/debugger_test.go Show resolved Hide resolved
gnovm/cmd/gno/run.go Show resolved Hide resolved
The connection is now initiated of the debugger state machine, so
the error can be processed from the start. It also allows slight
simplifcations.
@mvertes mvertes requested a review from deelawn as a code owner May 6, 2024 15:56
Also improve test coverage (now > 96% for debugger.go).
gnovm/pkg/gnolang/machine.go Outdated Show resolved Hide resolved
Copy link
Member

@thehowl thehowl left a comment

Choose a reason for hiding this comment

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

Approving, sorry this took long.

I have a few grievances about the code duplication. I'd really prefer if we didn't have multiple implementations of essentially the same functionality in the same VM; as I think these create a maintainability problem. I'd look, if possible, to proceed unifying the code for injectLocOnPanic / debugUpdateLocation; likewise for debugEvalExpr. (Also because, fun fact, we already do have a "minimalistic parser"; see go doc gnolang.X).

If you can undertake efforts of unification, I'd really appreciate it. It may seem like shallow work; but I really believe that in the long-run, it will help us to avoid having to fix issues in three different expression parsers.

Same for injectLocOnPanic. We will need to have good line reporting anyway, with #1981 (ie. having stacktraces on GnoVM panics), so it's probably best if we end up with a single, good implementation.

That said, thank you for undertaking the effort and taking the time to address review comments.

Merging.

@thehowl thehowl merged commit a901e79 into gnolang:master May 14, 2024
14 checks passed
@mvertes mvertes deleted the debugger branch May 14, 2024 20:48
@mvertes
Copy link
Contributor Author

mvertes commented May 14, 2024

Yes @thehowl, I will now look at unifying common parts as you suggest. Thanks for your thorough review and useful suggestions.

jefft0 pushed a commit to jefft0/gno that referenced this pull request May 15, 2024
![gno-debug](https://github.com/gnolang/gno/assets/5792239/96c50686-df6c-4dd8-a1d1-63f787a9328d)

We provide here an embedded interactive debugger to let the user control
and inspect its program at symbolic level, with the same features and
commands as classical debuggers: gdb, lldb or delve.

The debugger is enabled by setting the `-debug` flag in `gno run`
command, which loads the target program and immediately shows a debugger
prompt on the console:

	$ gno run -debug /tmp/my-program.gno
	Welcome to the Gnovm debugger. Type 'help' for list of commands.
	dbg>

Providing `-debug-addr` flag allows to start a remote debugging session,
and not interfer with the program stdin and stdout. For example, in a
first terminal:

	$ gno run -debug-addr :4000 /tmp/my-program.gno
	Waiting for debugger client to connect at :4000

And in a second terminal, using a netcat like nc(1):

	$ nc localhost 4000
	Welcome to the Gnovm debugger. Type 'help' for list of commands.
	dbg>

The debugger works by intercepting each execution step at virtual
machine level (each iteration within `Machine.Run` loop) to a callback,
which in turns can provide a debugger command REPL or check if the
execution can proceed to the next step, etc.

The general logic and structure is there. It is possible to `continue`,
`stepi`, `detach`, `print`, `stack`, etc and get a general feedback of
the user experience and the impact on the code.

Efforts are made to make this feature minimally intrusive in the actual
VM, and not interfering when the debugger is not used.

It is planned shortly after this PR is integrated to add the capacity to
attach to an already running program, and to taylor the data format for
existing debugging environments such as VScode, etc, as demand arises.

Resolves gnolang/hackerspace#54

<!-- please provide a detailed description of the changes made in this
pull request. -->

<details><summary>Contributors' checklist...</summary>

- [x] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: Morgan <morgan@morganbaz.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 🤖 gnovm Issues or PRs gnovm related
Projects
Status: Done
Status: Done
Development

Successfully merging this pull request may close these issues.

Add an interactive debugger in gnoVM
7 participants