Skip to content

Not unwinding catchframes properly after return-from in compiled code #494

Open
@Affonso-Gui

Description

@Affonso-Gui

Catch frames are not properly unwinded after a return-from statement if they are the first element in the local stack after compiled.

For example:

;; foo.l
(defun foo ()
  (catch :this
    (return-from foo 10)))

Compile with euscomp foo.l and then:

eus$ (load "foo.so")
eus$ (sys:list-all-catchers)
(:reploop-select 0 :eusexit)
eus$ (foo)
10
eus$ (sys:list-all-catchers)
;; Segmentation Fault.
;; in (system:list-all-catchers)
;; You are still in a signal handler.
;;Try reset or throw to upper level as soon as possible.
;; code=-1311861392 x=b1ce9440 addr=22

Looking at the compiled code, we see that we are trying to unwind until local+0. However, the catch frame is registered in local[0], so we should rewind for "local-1".

/*foo*/
static pointer fooF1foo(ctx,n,argv,env)
register context *ctx;
register int n; register pointer argv[]; pointer env;
{ register pointer *local=ctx->vsp, w, *fqv=qv;
  numunion nu;
	if (n!=0) maerror();
	{jmp_buf jb;
	w = fqv[0];
	ctx->vsp=local+0;
	mkcatchframe(ctx,w,(jmp_buf *)jb);
	if ((w=(pointer)eussetjmp(jb))!=0) { /*fsp=vsp;*/ goto fooCAT4;}
	w = makeint((eusinteger_t)10L);
	ctx->vsp=local+6;
	unwind(ctx,local+0);
	local[0]=w;
	goto fooBLK3;
	w = local[6];
fooCAT4:
	if (w==(pointer)(1)) w=makeint(0);
	restorecatch(ctx);};
	local[0]= w;
fooBLK3:
	ctx->vsp=local; return(local[0]);}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions