|
@ -405,7 +405,7 @@ format_offender(Off) -> |
|
|
[get_value(mod, Off), get_value(pid, Off)]); |
|
|
[get_value(mod, Off), get_value(pid, Off)]); |
|
|
MFArgs -> |
|
|
MFArgs -> |
|
|
%% regular supervisor |
|
|
%% regular supervisor |
|
|
{_, MFA} = format_mfa_md(MFArgs), |
|
|
|
|
|
|
|
|
{_, MFA} = formatMfaMd(MFArgs), |
|
|
|
|
|
|
|
|
%% In 2014 the error report changed from `name' to |
|
|
%% In 2014 the error report changed from `name' to |
|
|
%% `id', so try that first. |
|
|
%% `id', so try that first. |
|
@ -425,47 +425,47 @@ format_reason(Reason) -> |
|
|
|
|
|
|
|
|
-spec format_reason_md(Stacktrace :: any()) -> {Metadata :: [{atom(), any()}], String :: list()}. |
|
|
-spec format_reason_md(Stacktrace :: any()) -> {Metadata :: [{atom(), any()}], String :: list()}. |
|
|
format_reason_md({'function not exported', [{M, F, A}, MFA | _]}) -> |
|
|
format_reason_md({'function not exported', [{M, F, A}, MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
{_, Formatted2} = format_mfa_md({M, F, length(A)}), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
|
|
|
{_, Formatted2} = formatMfaMd({M, F, length(A)}), |
|
|
{[{reason, 'function not exported'} | Md], ["call to undefined function ", Formatted2, " from ", Formatted]}; |
|
|
{[{reason, 'function not exported'} | Md], ["call to undefined function ", Formatted2, " from ", Formatted]}; |
|
|
format_reason_md({'function not exported', [{M, F, A, _Props}, MFA | _]}) -> |
|
|
format_reason_md({'function not exported', [{M, F, A, _Props}, MFA | _]}) -> |
|
|
%% R15 line numbers |
|
|
%% R15 line numbers |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
{_, Formatted2} = format_mfa_md({M, F, length(A)}), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
|
|
|
{_, Formatted2} = formatMfaMd({M, F, length(A)}), |
|
|
{[{reason, 'function not exported'} | Md], ["call to undefined function ", Formatted2, " from ", Formatted]}; |
|
|
{[{reason, 'function not exported'} | Md], ["call to undefined function ", Formatted2, " from ", Formatted]}; |
|
|
format_reason_md({undef, [MFA | _]}) -> |
|
|
format_reason_md({undef, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, undef} | Md], ["call to undefined function ", Formatted]}; |
|
|
{[{reason, undef} | Md], ["call to undefined function ", Formatted]}; |
|
|
format_reason_md({bad_return, {_MFA, {'EXIT', Reason}}}) -> |
|
|
format_reason_md({bad_return, {_MFA, {'EXIT', Reason}}}) -> |
|
|
format_reason_md(Reason); |
|
|
format_reason_md(Reason); |
|
|
format_reason_md({bad_return, {MFA, Val}}) -> |
|
|
format_reason_md({bad_return, {MFA, Val}}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, bad_return} | Md], ["bad return value ", print_val(Val), " from ", Formatted]}; |
|
|
{[{reason, bad_return} | Md], ["bad return value ", print_val(Val), " from ", Formatted]}; |
|
|
format_reason_md({bad_return_value, Val}) -> |
|
|
format_reason_md({bad_return_value, Val}) -> |
|
|
{[{reason, bad_return}], ["bad return value: ", print_val(Val)]}; |
|
|
{[{reason, bad_return}], ["bad return value: ", print_val(Val)]}; |
|
|
format_reason_md({{bad_return_value, Val}, MFA}) -> |
|
|
format_reason_md({{bad_return_value, Val}, MFA}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, bad_return_value} | Md], ["bad return value: ", print_val(Val), " in ", Formatted]}; |
|
|
{[{reason, bad_return_value} | Md], ["bad return value: ", print_val(Val), " in ", Formatted]}; |
|
|
format_reason_md({{badrecord, Record}, [MFA | _]}) -> |
|
|
format_reason_md({{badrecord, Record}, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badrecord} | Md], ["bad record ", print_val(Record), " in ", Formatted]}; |
|
|
{[{reason, badrecord} | Md], ["bad record ", print_val(Record), " in ", Formatted]}; |
|
|
format_reason_md({{case_clause, Val}, [MFA | _]}) -> |
|
|
format_reason_md({{case_clause, Val}, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, case_clause} | Md], ["no case clause matching ", print_val(Val), " in ", Formatted]}; |
|
|
{[{reason, case_clause} | Md], ["no case clause matching ", print_val(Val), " in ", Formatted]}; |
|
|
format_reason_md({function_clause, [MFA | _]}) -> |
|
|
format_reason_md({function_clause, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, function_clause} | Md], ["no function clause matching ", Formatted]}; |
|
|
{[{reason, function_clause} | Md], ["no function clause matching ", Formatted]}; |
|
|
format_reason_md({if_clause, [MFA | _]}) -> |
|
|
format_reason_md({if_clause, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, if_clause} | Md], ["no true branch found while evaluating if expression in ", Formatted]}; |
|
|
{[{reason, if_clause} | Md], ["no true branch found while evaluating if expression in ", Formatted]}; |
|
|
format_reason_md({{try_clause, Val}, [MFA | _]}) -> |
|
|
format_reason_md({{try_clause, Val}, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, try_clause} | Md], ["no try clause matching ", print_val(Val), " in ", Formatted]}; |
|
|
{[{reason, try_clause} | Md], ["no try clause matching ", print_val(Val), " in ", Formatted]}; |
|
|
format_reason_md({badarith, [MFA | _]}) -> |
|
|
format_reason_md({badarith, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badarith} | Md], ["bad arithmetic expression in ", Formatted]}; |
|
|
{[{reason, badarith} | Md], ["bad arithmetic expression in ", Formatted]}; |
|
|
format_reason_md({{badmatch, Val}, [MFA | _]}) -> |
|
|
format_reason_md({{badmatch, Val}, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badmatch} | Md], ["no match of right hand value ", print_val(Val), " in ", Formatted]}; |
|
|
{[{reason, badmatch} | Md], ["no match of right hand value ", print_val(Val), " in ", Formatted]}; |
|
|
format_reason_md({emfile, _Trace}) -> |
|
|
format_reason_md({emfile, _Trace}) -> |
|
|
{[{reason, emfile}], "maximum number of file descriptors exhausted, check ulimit -n"}; |
|
|
{[{reason, emfile}], "maximum number of file descriptors exhausted, check ulimit -n"}; |
|
@ -490,18 +490,18 @@ format_reason_md({badarg, [MFA, MFA2 | _]}) -> |
|
|
case MFA of |
|
|
case MFA of |
|
|
{_M, _F, A, _Props} when is_list(A) -> |
|
|
{_M, _F, A, _Props} when is_list(A) -> |
|
|
%% R15 line numbers |
|
|
%% R15 line numbers |
|
|
{Md, Formatted} = format_mfa_md(MFA2), |
|
|
|
|
|
{_, Formatted2} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA2), |
|
|
|
|
|
{_, Formatted2} = formatMfaMd(MFA), |
|
|
{[{reason, badarg} | Md], |
|
|
{[{reason, badarg} | Md], |
|
|
["bad argument in call to ", Formatted2, " in ", Formatted]}; |
|
|
["bad argument in call to ", Formatted2, " in ", Formatted]}; |
|
|
{_M, _F, A} when is_list(A) -> |
|
|
{_M, _F, A} when is_list(A) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA2), |
|
|
|
|
|
{_, Formatted2} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA2), |
|
|
|
|
|
{_, Formatted2} = formatMfaMd(MFA), |
|
|
{[{reason, badarg} | Md], |
|
|
{[{reason, badarg} | Md], |
|
|
["bad argument in call to ", Formatted2, " in ", Formatted]}; |
|
|
["bad argument in call to ", Formatted2, " in ", Formatted]}; |
|
|
_ -> |
|
|
_ -> |
|
|
%% seems to be generated by a bad call to a BIF |
|
|
%% seems to be generated by a bad call to a BIF |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badarg} | Md], |
|
|
{[{reason, badarg} | Md], |
|
|
["bad argument in ", Formatted]} |
|
|
["bad argument in ", Formatted]} |
|
|
end; |
|
|
end; |
|
@ -509,26 +509,26 @@ format_reason_md({{badarg, Stack}, _}) -> |
|
|
format_reason_md({badarg, Stack}); |
|
|
format_reason_md({badarg, Stack}); |
|
|
format_reason_md({{badarity, {Fun, Args}}, [MFA | _]}) -> |
|
|
format_reason_md({{badarity, {Fun, Args}}, [MFA | _]}) -> |
|
|
{arity, Arity} = lists:keyfind(arity, 1, erlang:fun_info(Fun)), |
|
|
{arity, Arity} = lists:keyfind(arity, 1, erlang:fun_info(Fun)), |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badarity} | Md], |
|
|
{[{reason, badarity} | Md], |
|
|
[io_lib:format("fun called with wrong arity of ~w instead of ~w in ", |
|
|
[io_lib:format("fun called with wrong arity of ~w instead of ~w in ", |
|
|
[length(Args), Arity]), Formatted]}; |
|
|
[length(Args), Arity]), Formatted]}; |
|
|
format_reason_md({noproc, MFA}) -> |
|
|
format_reason_md({noproc, MFA}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, noproc} | Md], |
|
|
{[{reason, noproc} | Md], |
|
|
["no such process or port in call to ", Formatted]}; |
|
|
["no such process or port in call to ", Formatted]}; |
|
|
format_reason_md({{badfun, Term}, [MFA | _]}) -> |
|
|
format_reason_md({{badfun, Term}, [MFA | _]}) -> |
|
|
{Md, Formatted} = format_mfa_md(MFA), |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd(MFA), |
|
|
{[{reason, badfun} | Md], |
|
|
{[{reason, badfun} | Md], |
|
|
["bad function ", print_val(Term), " in ", Formatted]}; |
|
|
["bad function ", print_val(Term), " in ", Formatted]}; |
|
|
format_reason_md({Reason, [{M, F, A} | _]}) when is_atom(M), is_atom(F), is_integer(A) -> |
|
|
format_reason_md({Reason, [{M, F, A} | _]}) when is_atom(M), is_atom(F), is_integer(A) -> |
|
|
{Md, Formatted} = format_reason_md(Reason), |
|
|
{Md, Formatted} = format_reason_md(Reason), |
|
|
{_, Formatted2} = format_mfa_md({M, F, A}), |
|
|
|
|
|
|
|
|
{_, Formatted2} = formatMfaMd({M, F, A}), |
|
|
{Md, [Formatted, " in ", Formatted2]}; |
|
|
{Md, [Formatted, " in ", Formatted2]}; |
|
|
format_reason_md({Reason, [{M, F, A, Props} | _]}) when is_atom(M), is_atom(F), is_integer(A), is_list(Props) -> |
|
|
format_reason_md({Reason, [{M, F, A, Props} | _]}) when is_atom(M), is_atom(F), is_integer(A), is_list(Props) -> |
|
|
%% line numbers |
|
|
%% line numbers |
|
|
{Md, Formatted} = format_reason_md(Reason), |
|
|
{Md, Formatted} = format_reason_md(Reason), |
|
|
{_, Formatted2} = format_mfa_md({M, F, A, Props}), |
|
|
|
|
|
|
|
|
{_, Formatted2} = formatMfaMd({M, F, A, Props}), |
|
|
{Md, [Formatted, " in ", Formatted2]}; |
|
|
{Md, [Formatted, " in ", Formatted2]}; |
|
|
format_reason_md(Reason) -> |
|
|
format_reason_md(Reason) -> |
|
|
{Str, _} = rumTruncIo:print(Reason, 500), |
|
|
{Str, _} = rumTruncIo:print(Reason, 500), |
|
@ -536,38 +536,41 @@ format_reason_md(Reason) -> |
|
|
|
|
|
|
|
|
%% backwards compatability shim |
|
|
%% backwards compatability shim |
|
|
format_mfa(MFA) -> |
|
|
format_mfa(MFA) -> |
|
|
element(2, format_mfa_md(MFA)). |
|
|
|
|
|
|
|
|
|
|
|
-spec format_mfa_md(any()) -> {[{atom(), any()}], list()}. |
|
|
|
|
|
format_mfa_md({M, F, A}) when is_list(A) -> |
|
|
|
|
|
{FmtStr, Args} = format_args(A, [], []), |
|
|
|
|
|
{[{module, M}, {function, F}], io_lib:format("~w:~w(" ++ FmtStr ++ ")"
, [M, F | Args])}; |
|
|
|
|
|
format_mfa_md({M, F, A}) when is_integer(A) -> |
|
|
|
|
|
{[{module, M}, {function, F}], io_lib:format("~w:~w/~w", [M, F, A])}; |
|
|
|
|
|
format_mfa_md({M, F, A, Props}) when is_list(Props) -> |
|
|
|
|
|
|
|
|
element(2, formatMfaMd(MFA)). |
|
|
|
|
|
|
|
|
|
|
|
-spec formatMfaMd(any()) -> {[{atom(), any()}], list()}. |
|
|
|
|
|
formatMfaMd({M, F, A}) when is_list(A) -> |
|
|
|
|
|
ArgsStr = format_args(A, <<>>), |
|
|
|
|
|
{[{module, M}, {function, F}], eFtm:formatBin(<<"~w:~w(", ArgsStr/binary, ")">>, [M, F])}; |
|
|
|
|
|
formatMfaMd({M, F, A}) when is_integer(A) -> |
|
|
|
|
|
{[{module, M}, {function, F}], eFtm:formatBin(<<"~w:~w/~w";>>, [M, F, A])}; |
|
|
|
|
|
formatMfaMd({M, F, A, Props}) when is_list(Props) -> |
|
|
case get_value(line, Props) of |
|
|
case get_value(line, Props) of |
|
|
undefined -> |
|
|
undefined -> |
|
|
format_mfa_md({M, F, A}); |
|
|
|
|
|
|
|
|
formatMfaMd({M, F, A}); |
|
|
Line -> |
|
|
Line -> |
|
|
{Md, Formatted} = format_mfa_md({M, F, A}), |
|
|
|
|
|
{[{line, Line} | Md], [Formatted, io_lib:format(" line ~w", [Line])]} |
|
|
|
|
|
|
|
|
{Md, Formatted} = formatMfaMd({M, F, A}), |
|
|
|
|
|
{[{line, Line} | Md], <<Formatted/binary, " line ", (integer_to_binary(Line))/binary>>} |
|
|
end; |
|
|
end; |
|
|
format_mfa_md([{M, F, A} | _]) -> |
|
|
|
|
|
|
|
|
formatMfaMd([{M, F, A} | _]) -> |
|
|
%% this kind of weird stacktrace can be generated by a uncaught throw in a gen_server |
|
|
%% this kind of weird stacktrace can be generated by a uncaught throw in a gen_server |
|
|
format_mfa_md({M, F, A}); |
|
|
|
|
|
format_mfa_md([{M, F, A, Props} | _]) when is_list(Props) -> |
|
|
|
|
|
|
|
|
formatMfaMd({M, F, A}); |
|
|
|
|
|
formatMfaMd([{M, F, A, Props} | _]) when is_list(Props) -> |
|
|
%% this kind of weird stacktrace can be generated by a uncaught throw in a gen_server |
|
|
%% this kind of weird stacktrace can be generated by a uncaught throw in a gen_server |
|
|
%% TODO we might not always want to print the first MFA we see here, often it is more helpful |
|
|
%% TODO we might not always want to print the first MFA we see here, often it is more helpful |
|
|
%% to print a lower one, but it is hard to programatically decide. |
|
|
%% to print a lower one, but it is hard to programatically decide. |
|
|
format_mfa_md({M, F, A, Props}); |
|
|
|
|
|
format_mfa_md(Other) -> |
|
|
|
|
|
{[], io_lib:format("~w", [Other])}. |
|
|
|
|
|
|
|
|
|
|
|
format_args([], FmtAcc, ArgsAcc) -> |
|
|
|
|
|
{string:join(lists:reverse(FmtAcc), ", "), lists:reverse(ArgsAcc)}; |
|
|
|
|
|
format_args([H | T], FmtAcc, ArgsAcc) -> |
|
|
|
|
|
{Str, _} = rumTruncIo:print(H, 100), |
|
|
|
|
|
format_args(T, ["~s" | FmtAcc], [Str | ArgsAcc]). |
|
|
|
|
|
|
|
|
formatMfaMd({M, F, A, Props}); |
|
|
|
|
|
formatMfaMd(Other) -> |
|
|
|
|
|
{[], eFtm:formatBin(<<"~w">>, [Other])}. |
|
|
|
|
|
|
|
|
|
|
|
format_args([], ArgsAcc) -> |
|
|
|
|
|
ArgsAcc; |
|
|
|
|
|
format_args([H], ArgsAcc) -> |
|
|
|
|
|
Str = eFmt:formatBin(<<"~p">>, [H], [{charsLimit, 100}]), |
|
|
|
|
|
<<ArgsAcc/binary, Str/binary>>; |
|
|
|
|
|
format_args([H | T], ArgsAcc) -> |
|
|
|
|
|
Str = eFmt:formatBin(<<"~p">>, [H], [{charsLimit, 100}]), |
|
|
|
|
|
format_args(T, <<ArgsAcc/binary, Str/binary, ",">>). |
|
|
|
|
|
|
|
|
print_silly_list(L) when is_list(L) -> |
|
|
print_silly_list(L) when is_list(L) -> |
|
|
case rumStdlib:string_p(L) of |
|
|
case rumStdlib:string_p(L) of |
|
|