diff --git a/.github/container/Dockerfile b/.github/container/Dockerfile index b1c5aa5d1..1d238339a 100644 --- a/.github/container/Dockerfile +++ b/.github/container/Dockerfile @@ -1,5 +1,5 @@ #' Define default build variables -ARG OTP_VSN='27.3.4.2' +ARG OTP_VSN='27.3.4.3' ARG ELIXIR_VSN='1.18.4' ARG UID='9000' ARG USER='ejabberd' diff --git a/CONTAINER.md b/CONTAINER.md index b17d4fb40..e96081112 100644 --- a/CONTAINER.md +++ b/CONTAINER.md @@ -1072,7 +1072,7 @@ Let's summarize the differences between both container images. Legend: | Generated by | [container.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/container.yml) | [tests.yml](https://github.com/processone/docker-ejabberd/blob/master/.github/workflows/tests.yml) | | Built for | stable releases
`master` branch | stable releases
[`master` branch zip](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml) | | Architectures | `linux/amd64`
`linux/arm64` | `linux/amd64` | -| Software | Erlang/OTP 27.3.4.2-alpine
Elixir 1.18.4 | Alpine 3.19
Erlang/OTP 26.2
Elixir 1.15.7 | +| Software | Erlang/OTP 27.3.4.3-alpine
Elixir 1.18.4 | Alpine 3.22
Erlang/OTP 26.2
Elixir 1.18.3 | | Published in | [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd) | [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/)
[ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs) | | :black_square_button: **Additional content** | | [ejabberd-contrib](#ejabberd-contrib) | included | not included | diff --git a/ejabberdctl.template b/ejabberdctl.template index 58a0d8be6..0d124bead 100755 --- a/ejabberdctl.template +++ b/ejabberdctl.template @@ -553,7 +553,8 @@ case $1 in -noinput -hidden \ -eval 'net_kernel:connect_node('"'$PEER'"')' \ -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \ - -s erlang halt -output text + -eval 'halt(case net_adm:ping('"'$PEER'"') of pong -> 0; pang -> 1 end).' \ + -output text ;; started) set_dist_client diff --git a/include/ejabberd_stacktrace.hrl b/include/ejabberd_stacktrace.hrl deleted file mode 100644 index e65c5264f..000000000 --- a/include/ejabberd_stacktrace.hrl +++ /dev/null @@ -1,27 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% -%%% ejabberd, Copyright (C) 2002-2025 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%---------------------------------------------------------------------- - --ifdef(DEPRECATED_GET_STACKTRACE). --define(EX_RULE(Class, Reason, Stack), Class:Reason:Stack). --define(EX_STACK(Stack), Stack). --else. --define(EX_RULE(Class, Reason, _), Class:Reason). --define(EX_STACK(_), erlang:get_stacktrace()). --endif. diff --git a/mix.exs b/mix.exs index c5600b228..5b5be84f5 100644 --- a/mix.exs +++ b/mix.exs @@ -85,7 +85,6 @@ defmodule Ejabberd.MixProject do result = [{:d, :ELIXIR_ENABLED}] ++ cond_options() ++ Enum.map(includes, fn (path) -> {:i, path} end) ++ - if_version_above(~c"20", [{:d, :DEPRECATED_GET_STACKTRACE}]) ++ if_version_above(~c"20", [{:d, :HAVE_URI_STRING}]) ++ if_version_above(~c"20", [{:d, :HAVE_ERL_ERROR}]) ++ if_version_below(~c"21", [{:d, :USE_OLD_HTTP_URI}]) ++ diff --git a/rebar.config b/rebar.config index e3d42edce..1d0f9a8db 100644 --- a/rebar.config +++ b/rebar.config @@ -126,7 +126,6 @@ {erl_opts, [nowarn_deprecated_function, {i, "include"}, - {if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}}, {if_version_above, "20", {d, 'HAVE_ERL_ERROR'}}, {if_version_above, "20", {d, 'HAVE_URI_STRING'}}, {if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}}, diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index a31d7b1a6..cbe74fb08 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -32,7 +32,7 @@ -export([start/2, prep_stop/1, stop/1]). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + %%% %%% Application API diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 8c10041e5..11173f9e8 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -52,7 +52,7 @@ {get_lang, 1}]). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -type option() :: atom() | {atom(), global | binary()}. -type error_reason() :: {merge_conflict, atom(), binary()} | @@ -169,14 +169,14 @@ get_option({O, Host} = Opt) -> T -> T end, try ets:lookup_element(Tab, Opt, 2) - catch ?EX_RULE(error, badarg, St) when Host /= global -> - StackTrace = ?EX_STACK(St), - Val = get_option({O, global}), - ?DEBUG("Option '~ts' is not defined for virtual host '~ts'. " - "This is a bug, please report it with the following " - "stacktrace included:~n** ~ts", - [O, Host, misc:format_exception(2, error, badarg, StackTrace)]), - Val + catch + error:badarg:StackTrace when Host /= global -> + Val = get_option({O, global}), + ?DEBUG("Option '~ts' is not defined for virtual host '~ts'. " + "This is a bug, please report it with the following " + "stacktrace included:~n** ~ts", + [O, Host, misc:format_exception(2, error, badarg, StackTrace)]), + Val end. -spec set_option(option(), term()) -> ok. @@ -802,8 +802,9 @@ load_file(File) -> Err -> abort(Err) end - catch ?EX_RULE(Class, Reason, St) -> - {error, {exception, Class, Reason, ?EX_STACK(St)}} + catch + Class:Reason:Stack -> + {error, {exception, Class, Reason, Stack}} end. -spec commit() -> ok. diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index 88bd5e785..075854e40 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -39,7 +39,7 @@ -include("ejabberd_commands.hrl"). -include("ejabberd_http.hrl"). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -define(DEFAULT_VERSION, 1000000). @@ -331,11 +331,10 @@ try_call_command(Args, Auth, AccessCommands, Version) -> ?STATUS_ERROR}; throw:Error -> {io_lib:format("~p", [Error]), ?STATUS_ERROR}; - ?EX_RULE(A, Why, Stack) -> - StackTrace = ?EX_STACK(Stack), - {io_lib:format("Unhandled exception occurred executing the command:~n** ~ts", - [misc:format_exception(2, A, Why, StackTrace)]), - ?STATUS_ERROR} + A:Why:StackTrace -> + {io_lib:format("Unhandled exception occurred executing the command:~n** ~ts", + [misc:format_exception(2, A, Why, StackTrace)]), + ?STATUS_ERROR} end. -spec call_command(Args::[string()], diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl index 0fedc1dfc..8f378aa48 100644 --- a/src/ejabberd_hooks.erl +++ b/src/ejabberd_hooks.erl @@ -60,7 +60,7 @@ ). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -record(state, {}). -type subscriber() :: {Module :: atom(), Function :: atom(), InitArg :: any()}. @@ -455,17 +455,19 @@ safe_apply(Hook, Module, Function, Args) -> true -> apply(Module, Function, Args) end - catch ?EX_RULE(E, R, St) when E /= exit; R /= normal -> - Stack = ?EX_STACK(St), - ?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n" ++ - string:join( - ["** ~ts"| - ["** Arg " ++ integer_to_list(I) ++ " = ~p" - || I <- lists:seq(1, length(Args))]], - "~n"), - [Hook, Module, Function, length(Args), - misc:format_exception(2, E, R, Stack)|Args]), - 'EXIT' + catch + E:R:Stack when E /= exit; R /= normal -> + ?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n" ++ + string:join( + ["** ~ts" | [ "** Arg " ++ integer_to_list(I) ++ " = ~p" + || I <- lists:seq(1, length(Args)) ]], + "~n"), + [Hook, + Module, + Function, + length(Args), + misc:format_exception(2, E, R, Stack) | Args]), + 'EXIT' end. -spec call_subscriber_list([subscriber()], binary() | global, atom(), {atom(), atom(), integer(), list()} | list(), subscriber_event(), [subscriber()]) -> any(). @@ -480,18 +482,20 @@ call_subscriber_list([{Mod, Func, InitArg} | SubscriberList], Host, Hook, Callba try apply(Mod, Func, SubscriberArgs) of State -> call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, [{Mod, Func, State} | Result]) - catch ?EX_RULE(E, R, St) when E /= exit; R /= normal -> - Stack = ?EX_STACK(St), - ?ERROR_MSG("Hook subscriber ~p crashed when running ~p:~p/~p:~n" ++ - string:join( - ["** ~ts"| - ["** Arg " ++ integer_to_list(I) ++ " = ~p" - || I <- lists:seq(1, length(SubscriberArgs))]], - "~n"), - [Hook, Mod, Func, length(SubscriberArgs), - misc:format_exception(2, E, R, Stack)|SubscriberArgs]), - %% Do not append subscriber for next calls: - call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, Result) + catch + E:R:Stack when E /= exit; R /= normal -> + ?ERROR_MSG("Hook subscriber ~p crashed when running ~p:~p/~p:~n" ++ + string:join( + ["** ~ts" | [ "** Arg " ++ integer_to_list(I) ++ " = ~p" + || I <- lists:seq(1, length(SubscriberArgs)) ]], + "~n"), + [Hook, + Mod, + Func, + length(SubscriberArgs), + misc:format_exception(2, E, R, Stack) | SubscriberArgs]), + %% Do not append subscriber for next calls: + call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, Result) end. %%%---------------------------------------------------------------------- @@ -709,13 +713,11 @@ run_event_handlers(TracingOpts, Hook, Host, Event, EventArgs, RunType) -> _ -> ok catch - ?EX_RULE(E, R, St) -> - Stack = ?EX_STACK(St), - ?ERROR_MSG( + E:R:Stack -> + ?ERROR_MSG( "(~0p|~ts|~0p) Tracing event '~0p' handler exception(~0p): ~0p: ~0p", - [Hook, Host, erlang:self(), EventHandler, E, R, Stack] - ), - ok + [Hook, Host, erlang:self(), EventHandler, E, R, Stack]), + ok end end, EventHandlerList @@ -885,8 +887,7 @@ tracing_output(#{output_function := OutputF}, Text, Args) -> _ -> ok catch - ?EX_RULE(E, R, St) -> - Stack = ?EX_STACK(St), + E:R:Stack -> ?ERROR_MSG("Tracing output function exception(~0p): ~0p: ~0p", [E, R, Stack]), ok end; diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index b8e05dec4..709585145 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -39,7 +39,7 @@ -include("logger.hrl"). -include_lib("xmpp/include/xmpp.hrl"). -include("ejabberd_http.hrl"). --include("ejabberd_stacktrace.hrl"). + -include_lib("kernel/include/file.hrl"). -record(state, {sockmod, @@ -372,11 +372,11 @@ process(Handlers, Request) -> try HandlerModule:process(LocalPath, Request) catch - ?EX_RULE(Class, Reason, Stack) -> + Class:Reason:Stack -> ?ERROR_MSG( - "HTTP handler crashed: ~s", - [misc:format_exception(2, Class, Reason, ?EX_STACK(Stack))]), - erlang:raise(Class, Reason, ?EX_STACK(Stack)) + "HTTP handler crashed: ~s", + [misc:format_exception(2, Class, Reason, Stack)]), + erlang:raise(Class, Reason, Stack) end end, ejabberd_hooks:run(http_request_debug, [{LocalPath, Request}]), diff --git a/src/ejabberd_iq.erl b/src/ejabberd_iq.erl index 507820b20..5db539cab 100644 --- a/src/ejabberd_iq.erl +++ b/src/ejabberd_iq.erl @@ -36,7 +36,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -record(state, {expire = infinity :: timeout()}). -type state() :: #state{}. @@ -174,11 +174,11 @@ calc_checksum(Data) -> -spec callback(atom() | pid(), #iq{} | timeout, term()) -> any(). callback(undefined, IQRes, Fun) -> try Fun(IQRes) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to process iq response:~n~ts~n** ~ts", - [xmpp:pp(IQRes), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to process iq response:~n~ts~n** ~ts", + [xmpp:pp(IQRes), + misc:format_exception(2, Class, Reason, StackTrace)]) end; callback(Proc, IQRes, Ctx) -> try diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 34735cd2c..5d9557415 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -48,7 +48,7 @@ -include("logger.hrl"). -include_lib("stdlib/include/ms_transform.hrl"). -include_lib("xmpp/include/xmpp.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("translate.hrl"). -record(state, {}). diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl index 5b82dbb50..d9db27219 100644 --- a/src/ejabberd_mnesia.erl +++ b/src/ejabberd_mnesia.erl @@ -42,7 +42,7 @@ -define(NEED_RESET, [local_content, type]). -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -record(state, {tables = #{} :: tables(), schema = [] :: [{atom(), custom_schema()}]}). @@ -377,14 +377,15 @@ do_transform(OldAttrs, Attrs, Old) -> transform_fun(Module, Name) -> fun(Obj) -> try Module:transform(Obj) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to transform Mnesia table ~ts:~n" - "** Record: ~p~n" - "** ~ts", - [Name, Obj, - misc:format_exception(2, Class, Reason, StackTrace)]), - erlang:raise(Class, Reason, StackTrace) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to transform Mnesia table ~ts:~n" + "** Record: ~p~n" + "** ~ts", + [Name, + Obj, + misc:format_exception(2, Class, Reason, StackTrace)]), + erlang:raise(Class, Reason, StackTrace) end end. diff --git a/src/ejabberd_redis.erl b/src/ejabberd_redis.erl index 27e8775e1..c0e61c0e6 100644 --- a/src/ejabberd_redis.erl +++ b/src/ejabberd_redis.erl @@ -48,7 +48,7 @@ -define(CALL_TIMEOUT, 60*1000). %% 60 seconds -include("logger.hrl"). --include("ejabberd_stacktrace.hrl"). + -record(state, {connection :: pid() | undefined, num :: pos_integer(), @@ -114,9 +114,10 @@ multi(F) -> {error, _} = Err -> Err; Result -> get_result(Result) end - catch ?EX_RULE(E, R, St) -> - erlang:erase(?TR_STACK), - erlang:raise(E, R, ?EX_STACK(St)) + catch + E:R:St -> + erlang:erase(?TR_STACK), + erlang:raise(E, R, St) end; _ -> erlang:error(nested_transaction) diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index de088d8ba..236b5081a 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -70,7 +70,8 @@ -include("logger.hrl"). -include("ejabberd_router.hrl"). -include_lib("xmpp/include/xmpp.hrl"). --include("ejabberd_stacktrace.hrl"). + + -callback init() -> any(). -callback register_route(binary(), binary(), local_hint(), @@ -90,11 +91,11 @@ start_link() -> -spec route(stanza()) -> ok. route(Packet) -> try do_route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end. -spec route(jid(), jid(), xmlel() | stanza()) -> ok. diff --git a/src/ejabberd_router_sql.erl b/src/ejabberd_router_sql.erl index ad120d82f..2d7631476 100644 --- a/src/ejabberd_router_sql.erl +++ b/src/ejabberd_router_sql.erl @@ -32,7 +32,8 @@ -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). -include("ejabberd_router.hrl"). --include("ejabberd_stacktrace.hrl"). + + %%%=================================================================== %%% API @@ -141,13 +142,13 @@ row_to_route(Domain, {ServerHost, NodeS, PidS, LocalHintS} = Row) -> local_hint = dec_local_hint(LocalHintS)}] catch _:{bad_node, _} -> []; - ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to decode row from 'route' table:~n" - "** Row = ~p~n" - "** Domain = ~ts~n" - "** ~ts", - [Row, Domain, - misc:format_exception(2, Class, Reason, StackTrace)]), - [] + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to decode row from 'route' table:~n" + "** Row = ~p~n" + "** Domain = ~ts~n" + "** ~ts", + [Row, + Domain, + misc:format_exception(2, Class, Reason, StackTrace)]), + [] end. diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 448773612..0876ca584 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -53,7 +53,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("ejabberd_commands.hrl"). -include_lib("stdlib/include/ms_transform.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("translate.hrl"). -define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1). @@ -249,11 +249,11 @@ handle_info({mnesia_system_event, {mnesia_up, Node}}, State) -> {noreply, State}; handle_info({route, Packet}, State) -> try route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_info({'DOWN', _Ref, process, Pid, _Reason}, State) -> diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 296452736..d6d81fbbe 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -92,7 +92,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("ejabberd_commands.hrl"). -include("ejabberd_sm.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("translate.hrl"). -callback init() -> ok | {error, any()}. @@ -131,13 +131,14 @@ stop() -> %% @doc route arbitrary term to c2s process(es) route(To, Term) -> try do_route(To, Term), ok - catch ?EX_RULE(E, R, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route term to ~ts:~n" - "** Term = ~p~n" - "** ~ts", - [jid:encode(To), Term, - misc:format_exception(2, E, R, StackTrace)]) + catch + E:R:StackTrace -> + ?ERROR_MSG("Failed to route term to ~ts:~n" + "** Term = ~p~n" + "** ~ts", + [jid:encode(To), + Term, + misc:format_exception(2, E, R, StackTrace)]) end. -spec route(stanza()) -> ok. diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 0c29f039e..922fec14a 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -89,7 +89,7 @@ -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). --include("ejabberd_stacktrace.hrl"). + -record(state, {db_ref :: undefined | db_ref_pid() | odbc_connection_reference(), @@ -616,19 +616,20 @@ outer_transaction(F, NRestarts, _Reason) -> {atomic, Res} end catch - ?EX_RULE(throw, {aborted, Reason}, _) when NRestarts > 0 -> - maybe_restart_transaction(F, NRestarts, Reason, true); - ?EX_RULE(throw, {aborted, Reason}, Stack) when NRestarts =:= 0 -> - StackTrace = ?EX_STACK(Stack), - ?ERROR_MSG("SQL transaction restarts exceeded~n** " - "Restarts: ~p~n** Last abort reason: " - "~p~n** Stacktrace: ~p~n** When State " - "== ~p", - [?MAX_TRANSACTION_RESTARTS, Reason, - StackTrace, get(?STATE_KEY)]), - maybe_restart_transaction(F, NRestarts, Reason, true); - ?EX_RULE(_, Reason, _) -> - maybe_restart_transaction(F, 0, Reason, true) + throw:{aborted, Reason}:_ when NRestarts > 0 -> + maybe_restart_transaction(F, NRestarts, Reason, true); + throw:{aborted, Reason}:StackTrace when NRestarts =:= 0 -> + ?ERROR_MSG("SQL transaction restarts exceeded~n** " + "Restarts: ~p~n** Last abort reason: " + "~p~n** Stacktrace: ~p~n** When State " + "== ~p", + [?MAX_TRANSACTION_RESTARTS, + Reason, + StackTrace, + get(?STATE_KEY)]), + maybe_restart_transaction(F, NRestarts, Reason, true); + _:Reason:_ -> + maybe_restart_transaction(F, 0, Reason, true) end end. @@ -742,10 +743,9 @@ sql_query_internal(#sql_query{} = Query) -> {error, <<"terminated unexpectedly">>}; exit:{shutdown, _} -> {error, <<"shutdown">>}; - ?EX_RULE(Class, Reason, Stack) -> - StackTrace = ?EX_STACK(Stack), + Class:Reason:StackTrace -> ?ERROR_MSG("Internal error while processing SQL query:~n** ~ts", - [misc:format_exception(2, Class, Reason, StackTrace)]), + [misc:format_exception(2, Class, Reason, StackTrace)]), {error, <<"internal error">>} end, check_error(Res, Query); @@ -935,12 +935,11 @@ sql_query_format_res({selected, _, Rows}, SQLQuery) -> try [(SQLQuery#sql_query.format_res)(Row)] catch - ?EX_RULE(Class, Reason, Stack) -> - StackTrace = ?EX_STACK(Stack), + Class:Reason:StackTrace -> ?ERROR_MSG("Error while processing SQL query result:~n" "** Row: ~p~n** ~ts", [Row, - misc:format_exception(2, Class, Reason, StackTrace)]), + misc:format_exception(2, Class, Reason, StackTrace)]), [] end end, Rows), diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index a02e9178a..c123f6383 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -37,7 +37,7 @@ -include("logger.hrl"). -include_lib("xmpp/include/xmpp.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + -type component() :: ejabberd_sm | ejabberd_local. @@ -111,14 +111,14 @@ process_iq(_Host, Module, Function, IQ) -> ejabberd_router:route(ResIQ); ignore -> ok - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to process iq:~n~ts~n** ~ts", - [xmpp:pp(IQ), - misc:format_exception(2, Class, Reason, StackTrace)]), - Txt = ?T("Module failed to handle the query"), - Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang), - ejabberd_router:route_error(IQ, Err) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to process iq:~n~ts~n** ~ts", + [xmpp:pp(IQ), + misc:format_exception(2, Class, Reason, StackTrace)]), + Txt = ?T("Module failed to handle the query"), + Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang), + ejabberd_router:route_error(IQ, Err) end. -spec process_iq(module(), atom(), iq()) -> ignore | iq(). diff --git a/src/gen_mod.erl b/src/gen_mod.erl index dc3ba3c56..667ff5055 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -44,7 +44,7 @@ -include("logger.hrl"). -include_lib("stdlib/include/ms_transform.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("ejabberd_commands.hrl"). -record(ejabberd_module, @@ -187,16 +187,20 @@ start_module(Host, Module, Opts, Order) -> ets:delete(ejabberd_modules, {Module, Host}), erlang:error({bad_return, Module, Err}) end - catch ?EX_RULE(Class, Reason, Stack) -> - StackTrace = ?EX_STACK(Stack), - ets:delete(ejabberd_modules, {Module, Host}), - ErrorText = format_module_error( - Module, start, 2, - Opts, Class, Reason, - StackTrace), - ?CRITICAL_MSG(ErrorText, []), - maybe_halt_ejabberd(), - erlang:raise(Class, Reason, StackTrace) + catch + Class:Reason:StackTrace -> + ets:delete(ejabberd_modules, {Module, Host}), + ErrorText = format_module_error( + Module, + start, + 2, + Opts, + Class, + Reason, + StackTrace), + ?CRITICAL_MSG(ErrorText, []), + maybe_halt_ejabberd(), + erlang:raise(Class, Reason, StackTrace) end. -spec reload_modules(binary()) -> ok. @@ -246,14 +250,18 @@ reload_module(Host, Module, NewOpts, OldOpts, Order) -> {ok, Pid} when is_pid(Pid) -> {ok, Pid}; Err -> erlang:error({bad_return, Module, Err}) end - catch ?EX_RULE(Class, Reason, Stack) -> - StackTrace = ?EX_STACK(Stack), - ErrorText = format_module_error( - Module, reload, 3, - NewOpts, Class, Reason, - StackTrace), + catch + Class:Reason:StackTrace -> + ErrorText = format_module_error( + Module, + reload, + 3, + NewOpts, + Class, + Reason, + StackTrace), ?CRITICAL_MSG(ErrorText, []), - erlang:raise(Class, Reason, StackTrace) + erlang:raise(Class, Reason, StackTrace) end; false -> ?WARNING_MSG("Module ~ts doesn't support reloading " @@ -346,14 +354,15 @@ prep_stop_module_keep_config(Host, Module) -> try Module:prep_stop(Host) of _ -> ok - catch ?EX_RULE(error, undef, _St) -> - ok; - ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), + catch + error:undef:_St -> + ok; + Class:Reason:StackTrace -> ?ERROR_MSG("Failed to prepare stop module ~ts at ~ts:~n** ~ts", - [Module, Host, + [Module, + Host, misc:format_exception(2, Class, Reason, StackTrace)]), - error + error end. -spec stop_module_keep_config(binary(), atom()) -> error | ok. @@ -371,12 +380,13 @@ stop_module_keep_config(Host, Module) -> _ -> ets:delete(ejabberd_modules, {Module, Host}), ok - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), + catch + Class:Reason:StackTrace -> ?ERROR_MSG("Failed to stop module ~ts at ~ts:~n** ~ts", - [Module, Host, + [Module, + Host, misc:format_exception(2, Class, Reason, StackTrace)]), - error + error end. -spec add_registrations(binary(), module(), [registration()]) -> ok. diff --git a/src/mod_block_strangers.erl b/src/mod_block_strangers.erl index c0a85faf1..fd4e9974d 100644 --- a/src/mod_block_strangers.erl +++ b/src/mod_block_strangers.erl @@ -281,9 +281,9 @@ mod_doc() -> #{value => ?T("AccessName"), desc => ?T("The option is supposed to be used when 'allow_local_users' " - "and 'allow_transports' are not enough. It's an ACL where " - "'deny' means the message will be rejected (or a CAPTCHA " - "would be generated for a presence, if configured), and " + "and 'allow_transports' are not enough. It's an Access Rule where " + "'deny' means the stanza will be rejected; there's an exception " + "if option 'captcha' is configured. And " "'allow' means the sender is whitelisted and the stanza " "will pass through. The default value is 'none', which " "means nothing is whitelisted.")}}, @@ -314,8 +314,8 @@ mod_doc() -> {captcha, #{value => "true | false", desc => - ?T("Whether to generate CAPTCHA or not in response to " - "messages from strangers. See also section " - "_`basic.md#captcha|CAPTCHA`_" + ?T("Whether to generate CAPTCHA challenges in response to " + "incoming presence subscription requests from strangers. " + "See also section _`basic.md#captcha|CAPTCHA`_" " of the Configuration Guide. " "The default value is 'false'.")}}]}. diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 4d7e86777..087be0e72 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -36,7 +36,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("logger.hrl"). -include("ejabberd_http.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("translate.hrl"). -define(DEFAULT_API_VERSION, 1000000). @@ -148,8 +148,7 @@ process([Call | _], #request{method = 'POST', data = Data, ip = IPPort} = Req) - _:{error,{_,invalid_json}} = Err -> ?DEBUG("Bad Request: ~p", [Err]), badrequest_response(<<"Invalid JSON input">>); - ?EX_RULE(_Class, Error, Stack) -> - StackTrace = ?EX_STACK(Stack), + _Class:Error:StackTrace -> ?DEBUG("Bad Request: ~p ~p", [Error, StackTrace]), badrequest_response() end; @@ -166,8 +165,7 @@ process([Call | _], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) -> %% TODO We need to refactor to remove redundant error return formatting throw:{error, unknown_command} -> json_format({404, 44, <<"Command not found.">>}); - ?EX_RULE(_, Error, Stack) -> - StackTrace = ?EX_STACK(Stack), + _:Error:StackTrace -> ?DEBUG("Bad Request: ~p ~p", [Error, StackTrace]), badrequest_response() end; @@ -257,13 +255,15 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) -> {400, misc:atom_to_binary(Error)}; throw:Msg when is_list(Msg); is_binary(Msg) -> {400, iolist_to_binary(Msg)}; - ?EX_RULE(Class, Error, Stack) -> - StackTrace = ?EX_STACK(Stack), - ?ERROR_MSG("REST API Error: " - "~ts(~p) -> ~p:~p ~p", - [Call, hide_sensitive_args(Args), - Class, Error, StackTrace]), - {500, <<"internal_error">>} + Class:Error:StackTrace -> + ?ERROR_MSG("REST API Error: " + "~ts(~p) -> ~p:~p ~p", + [Call, + hide_sensitive_args(Args), + Class, + Error, + StackTrace]), + {500, <<"internal_error">>} end. handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) -> diff --git a/src/mod_mix.erl b/src/mod_mix.erl index ced8ada75..25216b6fc 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -44,7 +44,8 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("logger.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + + -callback init(binary(), gen_mod:opts()) -> ok | {error, db_failure}. -callback set_channel(binary(), binary(), binary(), @@ -319,11 +320,11 @@ handle_cast(Request, State) -> handle_info({route, Packet}, State) -> try route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_info(Info, State) -> diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 0ca31cb80..ffb8c25d7 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -85,7 +85,7 @@ -include("mod_muc.hrl"). -include("mod_muc_room.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + -type state() :: #{hosts := [binary()], server_host := binary(), @@ -454,11 +454,11 @@ handle_call({create, Room, Host, From, Nick, Opts}, _From, -spec handle_cast(term(), state()) -> {noreply, state()}. handle_cast({route_to_room, Packet}, #{server_host := ServerHost} = State) -> try route_to_room(Packet, ServerHost) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), + catch + Class:Reason:StackTrace -> ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_cast({room_destroyed, {Room, Host}, Pid}, @@ -483,11 +483,11 @@ handle_info({route, Packet}, #{server_host := ServerHost} = State) -> %% where mod_muc is not loaded. Such configuration %% is *highly* discouraged try route(Packet, ServerHost) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), + catch + Class:Reason:StackTrace -> ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_info({room_destroyed, {Room, Host}, Pid}, State) -> diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index b4148b33f..c90fde530 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -74,7 +74,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("translate.hrl"). -include("mod_muc_room.hrl"). --include("ejabberd_stacktrace.hrl"). + -define(MAX_USERS_DEFAULT_LIST, [5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]). @@ -1027,10 +1027,10 @@ terminate(Reason, _StateName, ok end end - catch ?EX_RULE(E, R, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Got exception on room termination:~n** ~ts", - [misc:format_exception(2, E, R, StackTrace)]) + catch + E:R:StackTrace -> + ?ERROR_MSG("Got exception on room termination:~n** ~ts", + [misc:format_exception(2, E, R, StackTrace)]) end. %%%---------------------------------------------------------------------- @@ -2468,6 +2468,10 @@ check_password(owner, _Affiliation, _Packet, _From, _StateData) -> %% Don't check pass if user is owner in MUC service (access_admin option) true; +check_password(_ServiceAffiliation, owner, _Packet, _From, + _StateData) -> + %% Don't check pass if user is owner in this room + true; check_password(_ServiceAffiliation, Affiliation, Packet, From, StateData) -> case (StateData#state.config)#config.password_protected @@ -3266,19 +3270,20 @@ process_item_change(Item, SD, UJID) -> maybe_send_affiliation(JID, A, SD1), SD1 end - catch ?EX_RULE(E, R, St) -> - StackTrace = ?EX_STACK(St), - FromSuffix = case UJID of - #jid{} -> - JidString = jid:encode(UJID), - <<" from ", JidString/binary>>; - undefined -> - <<"">> - end, - ?ERROR_MSG("Failed to set item ~p~ts:~n** ~ts", - [Item, FromSuffix, - misc:format_exception(2, E, R, StackTrace)]), - {error, xmpp:err_internal_server_error()} + catch + E:R:StackTrace -> + FromSuffix = case UJID of + #jid{} -> + JidString = jid:encode(UJID), + <<" from ", JidString/binary>>; + undefined -> + <<"">> + end, + ?ERROR_MSG("Failed to set item ~p~ts:~n** ~ts", + [Item, + FromSuffix, + misc:format_exception(2, E, R, StackTrace)]), + {error, xmpp:err_internal_server_error()} end. -spec unsubscribe_from_room(jid(), state()) -> ok | error. diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index 692ad146d..2d170ed68 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -40,7 +40,7 @@ -include("logger.hrl"). -include_lib("xmpp/include/xmpp.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + -define(PROCNAME, ejabberd_mod_proxy65_service). @@ -86,8 +86,8 @@ terminate(_Reason, #state{myhosts = MyHosts}) -> handle_info({route, Packet}, State) -> try route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), + catch + Class:Reason:StackTrace -> ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", [xmpp:pp(Packet), misc:format_exception(2, Class, Reason, StackTrace)]) diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 06f0af657..bd0aff20f 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -46,7 +46,7 @@ -include("pubsub.hrl"). -include("mod_roster.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("ejabberd_commands.hrl"). -define(STDTREE, <<"tree">>). @@ -748,11 +748,11 @@ handle_cast(Msg, State) -> handle_info({route, Packet}, State) -> try route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_info(Info, State) -> @@ -3819,9 +3819,9 @@ tree_action(Host, Function, Args) -> DBType = mod_pubsub_opt:db_type(ServerHost), Fun = fun () -> try tree_call(Host, Function, Args) - catch ?EX_RULE(Class, Reason, St) when DBType == sql -> - StackTrace = ?EX_STACK(St), - ejabberd_sql:abort({exception, Class, Reason, StackTrace}) + catch + Class:Reason:StackTrace when DBType == sql -> + ejabberd_sql:abort({exception, Class, Reason, StackTrace}) end end, Ret = case DBType of @@ -3919,15 +3919,15 @@ transaction(Host, Fun, Trans) -> do_transaction(ServerHost, Fun, Trans, DBType) -> F = fun() -> try Fun() - catch ?EX_RULE(Class, Reason, St) when (DBType == mnesia andalso - Trans == transaction) orelse - DBType == sql -> - StackTrace = ?EX_STACK(St), - Ex = {exception, Class, Reason, StackTrace}, - case DBType of - mnesia -> mnesia:abort(Ex); - sql -> ejabberd_sql:abort(Ex) - end + catch + Class:Reason:StackTrace when (DBType == mnesia andalso + Trans == transaction) orelse + DBType == sql -> + Ex = {exception, Class, Reason, StackTrace}, + case DBType of + mnesia -> mnesia:abort(Ex); + sql -> ejabberd_sql:abort(Ex) + end end end, Res = case DBType of diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 7765fc255..0f032cb02 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -61,7 +61,7 @@ -include("mod_roster.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("translate.hrl"). -define(ROSTER_CACHE, roster_cache). diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index a225ba23b..740ca41d2 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -51,7 +51,7 @@ -include_lib("xmpp/include/xmpp.hrl"). -include("mod_vcard.hrl"). -include("translate.hrl"). --include("ejabberd_stacktrace.hrl"). + -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). @@ -151,11 +151,11 @@ handle_cast(Cast, State) -> handle_info({route, Packet}, State) -> try route(Packet) - catch ?EX_RULE(Class, Reason, St) -> - StackTrace = ?EX_STACK(St), - ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", - [xmpp:pp(Packet), - misc:format_exception(2, Class, Reason, StackTrace)]) + catch + Class:Reason:StackTrace -> + ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts", + [xmpp:pp(Packet), + misc:format_exception(2, Class, Reason, StackTrace)]) end, {noreply, State}; handle_info(Info, State) -> diff --git a/tools/make-binaries b/tools/make-binaries index 51a348d16..22ad3e98c 100755 --- a/tools/make-binaries +++ b/tools/make-binaries @@ -65,13 +65,13 @@ fi rel_name='ejabberd' rel_vsn=$(git describe --tags | sed -e 's/-g.*//' -e 's/-/./' | tr -d '[:space:]') mix_vsn=$(mix_version "$rel_vsn") -crosstool_vsn='1.27.0' +crosstool_vsn='1.28.0' termcap_vsn='1.3.1' -expat_vsn='2.7.1' +expat_vsn='2.7.2' zlib_vsn='1.3.1' yaml_vsn='0.2.5' -ssl_vsn='3.5.2' -otp_vsn='27.3.4.2' +ssl_vsn='3.5.3' +otp_vsn='27.3.4.3' elixir_vsn='1.18.4' pam_vsn='1.6.1' # Newer Linux-PAM versions use Meson, we don't support that yet. png_vsn='1.6.45'