mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-23 21:13:18 -08:00
threading: fix race condition when _ecl_frs_push is interrupted with a call to ecl_unwind
If by chance env->frs_top->frs_val has the value ECL_PROTECT_TAG,
ecl_unwind will stop and call longjmp. However, at this point
setjmp has not yet been called, leading to a segmentation fault.
This commit is contained in:
parent
6d7ec733eb
commit
ca5ef0f977
4 changed files with 11 additions and 2 deletions
|
|
@ -532,6 +532,12 @@ frs_overflow(void) /* used as condition in list.d */
|
|||
ecl_frame_ptr
|
||||
_ecl_frs_push(register cl_env_ptr env, register cl_object val)
|
||||
{
|
||||
/* We store a dummy tag first, to make sure that it is safe to
|
||||
* interrupt this method with a call to ecl_unwind. Otherwise, a
|
||||
* stray ECL_PROTECT_TAG will lead to segfaults. AO_store_full is
|
||||
* needed to ensure that the CPU doesn't reorder the memory
|
||||
* stores. */
|
||||
AO_store_full((AO_t*)&(env->frs_top+1)->frs_val,(AO_t)ECL_DUMMY_TAG);
|
||||
ecl_frame_ptr output = ++env->frs_top;
|
||||
if (output >= env->frs_limit) {
|
||||
frs_overflow();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ cl_symbols[] = {
|
|||
{"T", CL_ORDINARY, NULL, -1, OBJNULL},
|
||||
{SYS_ "UNBOUND", SI_CONSTANT, si_unbound, 0, ECL_UNBOUND},
|
||||
{SYS_ "PROTECT-TAG", SI_ORDINARY, NULL, -1, OBJNULL},
|
||||
{SYS_ "DUMMY-TAG", SI_ORDINARY, NULL, -1, OBJNULL},
|
||||
{SYS_ "*RESTART-CLUSTERS*", SI_SPECIAL, NULL, -1, Cnil},
|
||||
{SYS_ "*HANDLER-CLUSTERS*", SI_SPECIAL, NULL, -1, Cnil},
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ cl_symbols[] = {
|
|||
{"T",NULL},
|
||||
{SYS_ "UNBOUND","si_unbound"},
|
||||
{SYS_ "PROTECT-TAG",NULL},
|
||||
{SYS_ "DUMMY-TAG",NULL},
|
||||
{SYS_ "*RESTART-CLUSTERS*",NULL},
|
||||
{SYS_ "*HANDLER-CLUSTERS*",NULL},
|
||||
|
||||
|
|
|
|||
|
|
@ -246,8 +246,9 @@ enum ecl_stype { /* symbol type */
|
|||
#define ECL_T ((cl_object)(cl_symbols+1))
|
||||
#define ECL_UNBOUND ((cl_object)(cl_symbols+2))
|
||||
#define ECL_PROTECT_TAG ((cl_object)(cl_symbols+3))
|
||||
#define ECL_RESTART_CLUSTERS ((cl_object)(cl_symbols+4))
|
||||
#define ECL_HANDLER_CLUSTERS ((cl_object)(cl_symbols+5))
|
||||
#define ECL_DUMMY_TAG ((cl_object)(cl_symbols+4))
|
||||
#define ECL_RESTART_CLUSTERS ((cl_object)(cl_symbols+5))
|
||||
#define ECL_HANDLER_CLUSTERS ((cl_object)(cl_symbols+6))
|
||||
#define ECL_NO_TL_BINDING ((cl_object)(1 << ECL_TAG_BITS))
|
||||
|
||||
struct ecl_symbol {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue