YottaDB / YDB

Mirrored from https://gitlab.com/YottaDB/DB/YDB
Other
76 stars 37 forks source link

[#169] Restore condition handler stack on trigger frame unwind only if it is a forced unwind #170

Closed nars1 closed 6 years ago

nars1 commented 6 years ago

gtm_trigger_fini() is passed a parameter indicating whether the unwind is forced or not. But this information is not currently passed to op_unwind() and in turn unw_mv_ent() which is where the MVST_TRIGR mv_stent is unwound. As part of that unwind, we currently reset the condition handler stack unconditionally (active_ch, ctxt etc.). But this is not the right thing to do if the unwind is not forced. An example invocation is from mdb_condition_handler() using the TRIGGER_BASE_FRAME_UNWIND_IF_NOMANSLAND macro (which will do the trigger base frame unwind if we are in what is defined as the no-mans-land). In that case, mdb_condition_handler() is about to do an UNWIND soon after the base frame unwind and will be caught by surprise if the condition handler stack is reset from under itself (e.g. it would do a longjmp to a different condition handler's jump target which can cause the process to terminate abnormally with a stack-smashing/SIGABRT/SIG-6 error).

Since op_unwind() and unw_mv_ent() are used in lots of places, the way this parameter is being passed is through a global TREF(trig_forced_unwind). This is set in gtm_trigger_fini() just before the call to op_unwind() and that resets it right away and uses a local copy to set this global just before invoking unw_mv_ent(). This way we do not need to worry about resetting this global in case of an error codepath.