aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-03-22 15:17:47 +0100
committerBjörn Gustavsson <[email protected]>2019-03-22 15:31:32 +0100
commitf810d541b5722c153ac29b302bb509164421b5e8 (patch)
tree692ce43bd0bf35f60898c1fe5c941bc01606038a /erts/emulator/beam/beam_emu.c
parentfcb89c6cba3be603575fa4ca68a8706861c8ebdc (diff)
downloadotp-f810d541b5722c153ac29b302bb509164421b5e8.tar.gz
otp-f810d541b5722c153ac29b302bb509164421b5e8.tar.bz2
otp-f810d541b5722c153ac29b302bb509164421b5e8.zip
beam_emu.c: Avoid triggering an assertion for the wrong reason
Before 2d2e78ad6e66 that introduced tail-recursive calls of BIFs, the stack was guaranteed not to be empty when `erlang:raise/3` was called from the `catch` block of a `try` (because the `try` had set up a stack frame that would be deallocated after the `raise` call). Now the stack can be empty, so the ASSERT() call in next_catch() that checks that there is a continuation pointer at the top of the stack may fail. Move the ASSERT() call to after check for empty stack. While at it, also add a comment of the reason for the assertion.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index d68d021679..73bf443372 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1479,9 +1479,15 @@ next_catch(Process* c_p, Eterm *reg) {
BeamInstr i_return_time_trace = beam_return_time_trace[0];
ptr = prev = c_p->stop;
- ASSERT(is_CP(*ptr));
ASSERT(ptr <= STACK_START(c_p));
if (ptr == STACK_START(c_p)) return NULL;
+
+ /*
+ * Better safe than sorry here. In debug builds, produce a core
+ * dump if the top of the stack doesn't point to a continuation
+ * pointer. In other builds, ignore a non-CP at the top of stack.
+ */
+ ASSERT(is_CP(*ptr));
if ((is_not_CP(*ptr) || (*cp_val(*ptr) != i_return_trace &&
*cp_val(*ptr) != i_return_to_trace &&
*cp_val(*ptr) != i_return_time_trace ))