aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <[email protected]>2016-02-22 22:16:53 +0100
committerJosé Valim <[email protected]>2016-02-23 08:37:40 +0100
commitc7e82c6b406b632a191c791a1bd2162bde08f692 (patch)
tree699ff115ae3892e483d3a941edf17fe0b69616fa
parente038cbe699acc19901e10b9569a3b783e900582d (diff)
downloadotp-c7e82c6b406b632a191c791a1bd2162bde08f692.tar.gz
otp-c7e82c6b406b632a191c791a1bd2162bde08f692.tar.bz2
otp-c7e82c6b406b632a191c791a1bd2162bde08f692.zip
Use compile source info in debugger
Prior to this commit, the debugger relied on a simple heuristic that traverses directory from the beam file to find a source file. The heuristic was maintained with this patch but, if it fails, it fallbacks to the source value in the module compile info. In order to illustrate how it works, one of the tests that could not find its source now passes successfully (showing the source lookup is more robust).
-rw-r--r--lib/debugger/src/int.erl18
-rw-r--r--lib/debugger/test/int_SUITE.erl18
2 files changed, 26 insertions, 10 deletions
diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl
index 4f54beb45b..1e43d1858a 100644
--- a/lib/debugger/src/int.erl
+++ b/lib/debugger/src/int.erl
@@ -547,7 +547,7 @@ load({Mod, Src, Beam, BeamBin, Exp, Abst}, Dist) ->
check_module(Mod) ->
case code:which(Mod) of
Beam when is_list(Beam) ->
- case find_src(Beam) of
+ case find_src(Mod, Beam) of
Src when is_list(Src) ->
check_application(Src),
case check_beam(Beam) of
@@ -608,7 +608,7 @@ check_application2("gs-"++_) -> throw({error,{app,gs}});
check_application2("debugger-"++_) -> throw({error,{app,debugger}});
check_application2(_) -> ok.
-find_src(Beam) ->
+find_src(Mod, Beam) ->
Src0 = filename:rootname(Beam) ++ ".erl",
case is_file(Src0) of
true -> Src0;
@@ -618,10 +618,22 @@ find_src(Beam) ->
filename:basename(Src0)]),
case is_file(Src) of
true -> Src;
- false -> error
+ false -> find_src_from_module(Mod)
end
end.
+find_src_from_module(Mod) ->
+ Compile = Mod:module_info(compile),
+ case lists:keyfind(source, 1, Compile) of
+ {source, Src} ->
+ case is_file(Src) of
+ true -> Src;
+ false -> error
+ end;
+ false ->
+ error
+ end.
+
find_beam(Mod, Src) ->
SrcDir = filename:dirname(Src),
BeamFile = atom_to_list(Mod) ++ code:objfile_extension(),
diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl
index 5f2e4dd84d..a4995e6ef4 100644
--- a/lib/debugger/test/int_SUITE.erl
+++ b/lib/debugger/test/int_SUITE.erl
@@ -245,14 +245,13 @@ interpretable(Config) when is_list(Config) ->
?line true = int:interpretable(filename:join([DataDir,lists1])),
?line true = code:del_path(DataDir),
- %% {error, no_src}
- ?line PrivDir = filename:join(?config(priv_dir, Config), ""),
- ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.beam"]),
+ %% true (from source)
+ PrivDir = filename:join(?config(priv_dir, Config), ""),
+ {ok, _} = file:copy(filename:join([DataDir,"lists1.beam"]),
filename:join([PrivDir,"lists1.beam"])),
- ?line true = code:add_patha(PrivDir),
-
- ?line {error, no_src} = int:interpretable(lists1),
- ?line ok = file:delete(filename:join([PrivDir,"lists1.beam"])),
+ true = code:add_patha(PrivDir),
+ true = int:interpretable(lists1),
+ ok = file:delete(filename:join([PrivDir,"lists1.beam"])),
%% {error, no_beam}
Src = filename:join([PrivDir,"lists1.erl"]),
@@ -267,6 +266,11 @@ interpretable(Config) when is_list(Config) ->
?line ok = file:delete(Src),
?line true = code:del_path(PrivDir),
+ %% {error, no_src}
+ {ok, lists2, Binary} = compile:forms([{attribute,1,module,lists2}], []),
+ code:load_binary(lists2, "unknown", Binary),
+ {error, no_src} = int:interpretable(lists2),
+
%% {error, badarg}
?line {error, badarg} = int:interpretable(pride),
?line {error, badarg} = int:interpretable("prejudice.erl"),