From ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 5 May 2017 05:23:54 +0200 Subject: Clear p->fvalue when handling a try/catch p->fvalue will be set by BIFs that generate exceptions (such as throw/1), and it will not be cleared before another exception is generated. Potentially, p->fvalue may contain a huge term (e.g. after throw(HugeTerm)) which will be kept in the heap. We can shorten the lifetime of f->value by clearing it in the instructions that handle catches: catch_end and try_end. That is safe because BEAM code will never access p->fvalue. If BEAM code needs to rethrow an exception it will use a reference to the value passed in an X register. The reason that p->fvalue must not be cleared already in handle_error() is that native code trap handlers will use it. (See the comment before handle_error() and the comment at the end of handle_error() in beam_emu.c for some more information about exception handling.) --- erts/emulator/beam/beam_emu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 311bb94242..a90e6a0ba8 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1814,6 +1814,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; if (x(1) == am_throw) { r(0) = x(2); } else { @@ -1843,6 +1844,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; r(0) = x(1); x(1) = x(2); x(2) = x(3); -- cgit v1.2.3