From bfee20e61e9f6f4ad2e2d39d68c9c94910c67bac Mon Sep 17 00:00:00 2001 From: Steve Strong Date: Wed, 13 Mar 2019 11:36:04 +0000 Subject: Bind erlang:get_stacktrace prior to making other calls If we bind too late there might be an exception triggered in the terminate function and we will not get the correct stacktrace as a result. --- src/cowboy_handler.erl | 3 ++- src/cowboy_loop.erl | 3 ++- src/cowboy_rest.erl | 3 ++- src/cowboy_websocket.erl | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cowboy_handler.erl b/src/cowboy_handler.erl index 26aa30e..bf42b77 100644 --- a/src/cowboy_handler.erl +++ b/src/cowboy_handler.erl @@ -47,8 +47,9 @@ execute(Req, Env=#{handler := Handler, handler_opts := HandlerOpts}) -> {Mod, Req2, State, Opts} -> Mod:upgrade(Req2, Env, Handler, State, Opts) catch Class:Reason -> + StackTrace = erlang:get_stacktrace(), terminate({crash, Class, Reason}, Req, HandlerOpts, Handler), - erlang:raise(Class, Reason, erlang:get_stacktrace()) + erlang:raise(Class, Reason, StackTrace) end. -spec terminate(any(), Req | undefined, any(), module()) -> ok when Req::cowboy_req:req(). diff --git a/src/cowboy_loop.erl b/src/cowboy_loop.erl index 2e5ecdb..603c939 100644 --- a/src/cowboy_loop.erl +++ b/src/cowboy_loop.erl @@ -82,8 +82,9 @@ call(Req0, Env, Handler, HandlerState0, Message) -> {stop, Req, HandlerState} -> terminate(Req, Env, Handler, HandlerState, stop) catch Class:Reason -> + StackTrace = erlang:get_stacktrace(), cowboy_handler:terminate({crash, Class, Reason}, Req0, HandlerState0, Handler), - erlang:raise(Class, Reason, erlang:get_stacktrace()) + erlang:raise(Class, Reason, StackTrace) end. suspend(Req, Env, Handler, HandlerState) -> diff --git a/src/cowboy_rest.erl b/src/cowboy_rest.erl index 010bf05..7be3e26 100644 --- a/src/cowboy_rest.erl +++ b/src/cowboy_rest.erl @@ -1622,8 +1622,9 @@ switch_handler({switch_handler, Mod, Opts}, Req, #state{handler_state=HandlerSta -spec error_terminate(cowboy_req:req(), #state{}, atom(), any()) -> no_return(). error_terminate(Req, #state{handler=Handler, handler_state=HandlerState}, Class, Reason) -> + StackTrace = erlang:get_stacktrace(), cowboy_handler:terminate({crash, Class, Reason}, Req, HandlerState, Handler), - erlang:raise(Class, Reason, erlang:get_stacktrace()). + erlang:raise(Class, Reason, StackTrace). terminate(Req, #state{handler=Handler, handler_state=HandlerState}) -> Result = cowboy_handler:terminate(normal, Req, HandlerState, Handler), diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index a94a5ce..9fc2752 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -503,9 +503,10 @@ handler_call(State=#state{handler=Handler}, HandlerState, {stop, HandlerState2} -> websocket_close(State, HandlerState2, stop) catch Class:Reason -> + StackTrace = erlang:get_stacktrace(), websocket_send_close(State, {crash, Class, Reason}), handler_terminate(State, HandlerState, {crash, Class, Reason}), - erlang:raise(Class, Reason, erlang:get_stacktrace()) + erlang:raise(Class, Reason, StackTrace) end. -spec handler_call_result(#state{}, any(), parse_state(), fun(), commands()) -> no_return(). -- cgit v1.2.3