Skip to content

Commit

Permalink
Merge pull request erlang#9399 from lukaszsamson/ls-fix-int-crash
Browse files Browse the repository at this point in the history
Handle load_binary result in debugger int:load

OTP-19484
  • Loading branch information
bjorng authored Feb 10, 2025
2 parents f4f2d1a + 09a1a60 commit 04afeaa
Showing 1 changed file with 49 additions and 20 deletions.
69 changes: 49 additions & 20 deletions lib/debugger/src/int.erl
Original file line number Diff line number Diff line change
Expand Up @@ -866,28 +866,57 @@ check(Mod) when is_atom(Mod) -> catch check_module(Mod);
check(File) when is_list(File) -> catch check_file(File).

load({Mod, Src, Beam, BeamBin, Exp, Abst}, Dist) ->
_ = everywhere(Dist,
fun() ->
code:purge(Mod),
erts_debug:breakpoint({Mod,'_','_'}, false),
{module,Mod} = code:load_binary(Mod, Beam, BeamBin)
end),
case erl_prim_loader:read_file(filename:absname(Src)) of
{ok, SrcBin} ->
MD5 = code:module_md5(BeamBin),
SrcBin1 = unicode:characters_to_binary(SrcBin, enc(SrcBin)),
true = is_binary(SrcBin1),
Bin = term_to_binary({interpreter_module,Exp,Abst,SrcBin1,MD5}),
{module, Mod} = dbg_iserver:safe_call({load, Mod, Src, Bin}),
_ = everywhere(Dist,
fun() ->
true = erts_debug:breakpoint({Mod,'_','_'}, true) > 0
end),
{module, Mod};
error ->
error
RawLoadResult = everywhere(Dist,
fun() ->
code:purge(Mod),
erts_debug:breakpoint({Mod, '_', '_'}, false),
code:load_binary(Mod, Beam, BeamBin)
end),
LoadResult = extract_result(RawLoadResult),
case LoadResult of
{module, Mod} ->
case erl_prim_loader:read_file(filename:absname(Src)) of
{ok, SrcBin} ->
MD5 = code:module_md5(BeamBin),
SrcBin1 = unicode:characters_to_binary(SrcBin, enc(SrcBin)),
true = is_binary(SrcBin1),
Bin = term_to_binary({interpreter_module, Exp, Abst, SrcBin1, MD5}),
{module, Mod} = dbg_iserver:safe_call({load, Mod, Src, Bin}),
_ = everywhere(Dist,
fun() ->
true = erts_debug:breakpoint({Mod, '_', '_'}, true) > 0
end),
{module, Mod};
error ->
error
end;
{error, _} ->
error;
{badrpc, _} ->
error
end.

extract_result({Results, _BadNodes}) when is_list(Results) ->
%% In distributed mode, rpc:multicall returns {Results, BadNodes}.
%% Look for any successful result in the list.
case lists:filter(fun
({module, _}) -> true;
(_) -> false
end, Results) of
[] ->
%% No node succeeded; return the first result from Results,
%% which should be an error tuple or badrpc tuple.
case Results of
[First | _] -> First;
[] -> error
end;
[Success | _] ->
Success
end;
extract_result(Result) ->
%% For local (non-distributed) calls, the result is returned directly.
Result.

check_module(Mod) ->
case code:which(Mod) of
Beam when is_list(Beam) ->
Expand Down

0 comments on commit 04afeaa

Please sign in to comment.