diff options
author | Guilherme Andrade <g@gandrade.net> | 2017-08-05 22:14:40 +0100 |
---|---|---|
committer | Guilherme Andrade <g@gandrade.net> | 2017-08-05 22:14:40 +0100 |
commit | e8e20e32a8683daa6848c0bb0b715eae842bc4a9 (patch) | |
tree | 80d0a31a12b3357cf3244980ebd41d1e5ea97882 | |
parent | 330baef58fa02c8cddc31c5c373fc5bda30f11dd (diff) |
Don't crash when determining the source of undefined functions in stripped modules
This can be reproduced by running xref analysis against a rebar3
plugin project which doesn't list rebar3 as an explicit dependency
-- calls to certain bundled modules ('rebar_state', 'rebar_api',
'ec_cnv', ...) will result in a failed pattern match as these modules
appear to have had their abstract code stripped.
-rw-r--r-- | src/rebar_prv_xref.erl | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/rebar_prv_xref.erl b/src/rebar_prv_xref.erl index db0f4e4..f358787 100644 --- a/src/rebar_prv_xref.erl +++ b/src/rebar_prv_xref.erl @@ -281,12 +281,21 @@ find_mfa_source({M, F, A}) -> end. find_function_source(M, F, A, Bin) -> - AbstractCode = beam_lib:chunks(Bin, [abstract_code]), - {ok, {M, [{abstract_code, {raw_abstract_v1, Code}}]}} = AbstractCode, + ChunksLookup = beam_lib:chunks(Bin, [abstract_code]), + {ok, {M, [{abstract_code, AbstractCodeLookup}]}} = ChunksLookup, + case AbstractCodeLookup of + no_abstract_code -> + % There isn't much else we can do at this point + {module_not_found, function_not_found}; + {raw_abstract_v1, AbstractCode} -> + find_function_source_in_abstract_code(F, A, AbstractCode) + end. + +find_function_source_in_abstract_code(F, A, AbstractCode) -> %% Extract the original source filename from the abstract code - [{attribute, _, file, {Source, _}} | _] = Code, + [{attribute, _, file, {Source, _}} | _] = AbstractCode, %% Extract the line number for a given function def - Fn = [E || E <- Code, + Fn = [E || E <- AbstractCode, safe_element(1, E) == function, safe_element(3, E) == F, safe_element(4, E) == A], |