diff options
author | Björn Gustavsson <[email protected]> | 2019-05-23 07:22:41 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-05-23 10:12:23 +0200 |
commit | 5959fb00182048d50f55d04684723d383d1aeee8 (patch) | |
tree | f01d55472255bf60398116eb719ede79dae4011c /erts/emulator/beam/beam_emu.c | |
parent | 7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff) | |
download | otp-5959fb00182048d50f55d04684723d383d1aeee8.tar.gz otp-5959fb00182048d50f55d04684723d383d1aeee8.tar.bz2 otp-5959fb00182048d50f55d04684723d383d1aeee8.zip |
Fix sticky class in exception
When catching an exception re-throwing with a changed
class, the class could be changed to the original class
if the exception got caught and rethrown in (for example)
an after block:
sticky_class() ->
try
try
throw(reason)
catch
throw:Reason:Stack ->
erlang:raise(error, Reason, Stack)
end
after
ok
end.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 3af0838794..ec4f9b4339 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -422,6 +422,7 @@ static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc); static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, ErtsCodeMFA *bif_mfa, Eterm args); static struct StackTrace * get_trace_from_exc(Eterm exc); +static Eterm *get_freason_ptr_from_exc(Eterm exc); static Eterm make_arglist(Process* c_p, Eterm* reg, int a); void @@ -1904,6 +1905,25 @@ static int is_raised_exc(Eterm exc) { } } +static Eterm *get_freason_ptr_from_exc(Eterm exc) { + static Eterm dummy_freason; + struct StackTrace* s; + + if (exc == NIL) { + /* + * Is is not exactly clear when exc can be NIL. Probably only + * when the exception has been generated from native code. + * Return a pointer to an Eterm that can be safely written and + * ignored. + */ + return &dummy_freason; + } else { + ASSERT(is_list(exc)); + s = (struct StackTrace *) big_val(CDR(list_val(exc))); + return &s->freason; + } +} + /* * Creating a list with the argument registers */ |