From e8e20e32a8683daa6848c0bb0b715eae842bc4a9 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Sat, 5 Aug 2017 22:14:40 +0100 Subject: 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. --- src/rebar_prv_xref.erl | 17 +++++++++++++---- 1 file 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], -- cgit v1.1