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

Experimental debugger API #9604

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Conversation

jcpetruzza
Copy link
Contributor

This PR is the complement to #9334 (adding the debug_line instruction) and together with #8670 (pausing proc timers) add the support on the VM that drives the new edb debugger.

These are main parts of the PR:

  • A new +D emulator flag is added. When given, the VM becomes "debuggable", which means that when modules are loaded, the debug_line instruction is instrumented similar to what is currently done for tracing-breakpoints, so that one can enable and disable breakpoints on that particular lines.

  • An experimental erl_debugger module is added, with a new debugging API. Essentially, it allows a single, local, process to be registered as the "debugger" process for the node. This process is the one that will receive messages notifying that a process hit a breakpoint. This way, we can decouple debugger implementations that consume this API (like edb) from OTP itself.

  • The erl_debugger module also exposes new BIFs to inspect X and Y registers of a suspended process. Together with the new code-information BIFs added in Add support for debug information for a native debugger #9334, this let's a debugger show the values of variables in scope for a suspended process.

We add a new erl_debugger module to the kernel
application, that will provides an API for writing
debuggers. Here we set up the general interface,
with a stub for "setting a breakpoint" as the only
debugging primitive. In the next commits we first
implement the "breakpoint" primitive, and later
add additional ones.

About the general design:

- A node needs to have debugging support enabled
  on startup with the `+D` option and this can't be
  enabled afterwards. This gives admins a way to
  prevent processes from blocking on prod due to an
  accidental debugger usage, etc.
- Debugging primitives based on code instrumentation
  can be individually enabled/disabled, etc.
- A debugger is an Erlang process; there can be at most
  one debugger process per node.
- The system will communicate with the debugger process
  via `debugger_events` messages. For now we introduce
  only one message for notifying that a process hit
  a breakpoint
On module loading, `debug_line` are currently ignored.  Now, when
debugger support is enabled (and the line-breakpoint instrumentation
enabled), we emit a `i_debug_line` instruction. For now, we only use
it to add entries to the line-table, the actual breakpoint
instrumentation is introduced next.
The logic was duplicated and out of sync. We want to add another internal
function for dealing with breakpoints, so better to have all in one place
We add trampolines on each debug_line instruction, similar
to the ones used on function entry. The main difference is that
we need to save all live X-registers on the stack before calling
`erts_internal:breakpoint/4`, and thus may require a GC.
We want to reuse the logic currently use to flip beakpoints for tracing, etc.
However, at the moment, the functions where this happens not only change the
code, but also set some flags value that are specific to those cases..

We factor out this part of the code to their own functions. In doing so, we observe
that for x86-64, the code was referring to `BEAM_ASM_FUNC_PROLOGUE_SIZE` to determine
the offset to use when "disabling" a breakpoint that doesn't seem relevant. The value
is indeed 6 (see, e.g., the assertion on the "enabling" case), and this corresponds to:
  - 1 byte for the NOP 0x90 due to call alignment
  - 1 byte for the opcode of a `CALL`
  - 4 bytes for the 32-bit offset of the call target
Copy link
Contributor

github-actions bot commented Mar 18, 2025

CT Test Results

    4 files    201 suites   1h 55m 13s ⏱️
3 091 tests 2 800 ✅ 289 💤 2 ❌
4 067 runs  3 705 ✅ 360 💤 2 ❌

For more details on these failures, see this check.

Results for commit 54a88a9.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@bjorng bjorng added team:VM Assigned to OTP team VM feature labels Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature team:VM Assigned to OTP team VM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants