Skip to content

Commit

Permalink
Import OTP toolchain wich changes in stack-frames format
Browse files Browse the repository at this point in the history
Summary:
# Context
At the moment, the `erl_debugger:stack_frames/2` function gives us the mfa ./ line of each frame, plus the frame slots (Y-regs and exception-handlers).

# Problem
In order to implement stepping correctly, we need a way store the stack-frames at the moment the stepping started and, when hitting an internal breakpoint, compare it to the current stack-frames to understand if we are on the same function call, we are a frame above, below or we bounced.

However, with only mfa/line there is currently not enough information to know if we have "bounced" or not, as we could have more than once call to a function per line.

# This diff
So we extended the `erl_debugger:stack_frames()` so that it includes the "continuation pointer" of each stack-frame, essentially, the address of the code that will be executed when control goes back to that frame. THis wasy, we can uniquely distinguish frames, even if they correspond to code "on the same line".

Notice that here we just import the new toolchain, and make the code fixes so that the new way in which stack-frames is returned doesn't break existing code.

Changes on the OTP side are [here](https://github.com/jcpetruzza/otp/compare/edb-2025-01-23..edb-2025-01-24)

Reviewed By: thizanne

Differential Revision: D68637176

fbshipit-source-id: 1c7ee5202b742b8beec071cd7722fa13c9227020
  • Loading branch information
jcpetruzza authored and facebook-github-bot committed Jan 27, 2025
1 parent d2af853 commit fbae51a
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "otp"]
path = otp
url = https://github.com/jcpetruzza/otp
branch = edb-2025-01-23
branch = edb-2025-01-24
10 changes: 5 additions & 5 deletions src/edb_server_inspect.erl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ format_stack_frames(RawFrames) ->
-spec format_stack_frames_1([RawFrame], Acc) -> Acc when
RawFrame :: erl_debugger:stack_frame(),
Acc :: [edb:stack_frame()].
format_stack_frames_1([{_FrameNo, Terminator, []}], Acc) when is_atom(Terminator) ->
format_stack_frames_1([{_FrameNo, Terminator, #{slots := []}}], Acc) when is_atom(Terminator) ->
% Stuff like '<terminate process normally>' are not useful to the user
lists:reverse(Acc);
format_stack_frames_1([{_FrameNo, '<breakpoint>', _} | Rest], _Acc) ->
Expand All @@ -71,7 +71,7 @@ format_stack_frames_1([{FrameNo, 'unknown function', _} | RawFrames], Acc) ->
line => undefined
},
format_stack_frames_1(RawFrames, [FormattedFrame | Acc]);
format_stack_frames_1([{FrameNo, {MFA = {M, _, _}, Line}, _Yregs} | RawFrames], Acc) ->
format_stack_frames_1([{FrameNo, #{function := MFA = {M, _, _}, line := Line}, _FrameInfo} | RawFrames], Acc) ->
FormattedFrame = #{
id => FrameNo,
mfa => MFA,
Expand All @@ -94,7 +94,7 @@ stack_frame_vars(Pid, FrameId, MaxTermSize, RawFrames, Opts) ->
case lookup_raw_frame(FrameId, RawFrames) of
undefined ->
undefined;
{{FrameId, FrameFun, FrameSlots}, XRegsLocation} ->
{{FrameId, FrameFun, #{slots := FrameSlots}}, XRegsLocation} ->
YRegs = #{yregs => stack_frame_y_regs(Pid, {FrameId, FrameSlots}, MaxTermSize)},

XRegs =
Expand All @@ -116,7 +116,7 @@ stack_frame_vars(Pid, FrameId, MaxTermSize, RawFrames, Opts) ->
]
}
end;
{BpFrameId, _, BpFrameSlots} ->
{BpFrameId, _, #{slots := BpFrameSlots}} ->
% We are on the top-frame, but for a process that hit a breakpoint. We
% are given the "breakpoint frame" were all live X regs were saved.
% So we can retrieve them from this frame (as Y regs).
Expand All @@ -126,7 +126,7 @@ stack_frame_vars(Pid, FrameId, MaxTermSize, RawFrames, Opts) ->
ResolveLocalVars = maps:get(resolve_local_vars, Opts),
LocalVars =
case FrameFun of
{{M, _F, _A}, Line} when ResolveLocalVars, is_atom(M), is_integer(Line) ->
#{function := {M, _F, _A}, line := Line} when ResolveLocalVars, is_atom(M), is_integer(Line) ->
case get_debug_info(M, Line) of
{error, _} ->
#{};
Expand Down

0 comments on commit fbae51a

Please sign in to comment.