1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-09 21:40:33 +02:00

fix stack corruption on vm-save-stack; more robust with nonlocal exits

* module/system/repl/command.scm: Coerce rationals to floats.

* module/system/vm/program.scm (program-documentation): Fix a typo, doh!

* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
  reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
  exit from a vm_run.
  (vm_heapify_frames_1): Don't repack the stack, it causes stack
  corruption. I think we need spaghetti stacks to handle continuations,
  not separate heap frames. I don't think call/cc is working now.
  (vm-save-stack): Don't call heapify_frames, that modifies the stack
  that we're copying. Instead call its helper, heapify_1.

* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.

* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
  checks without having these macros defined, define them as empty.
  Happens on x86-64.

* src/vm_system.c (halt): End the dynwind before we return from the VM.

* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
  cause they can do a nonlocal exit.
This commit is contained in:
Andy Wingo 2008-08-07 19:04:25 +02:00
parent 68a2e18a04
commit 17d1b4bffd
7 changed files with 56 additions and 5 deletions

View file

@ -301,7 +301,7 @@ Time execution."
(gc-end (gc-run-time))
(vms-end (vm-stats (repl-vm repl))))
(define (get proc start end)
(/ (- (proc end) (proc start)) internal-time-units-per-second))
(exact->inexact (/ (- (proc end) (proc start)) internal-time-units-per-second)))
(repl-print repl result)
(display "clock utime stime cutime cstime gctime\n")
(format #t "~5,2F ~5,2F ~5,2F ~6,2F ~6,2F ~6,2F\n"

View file

@ -59,5 +59,5 @@
(assq-ref (program-properties proc) prop))
(define (program-documentation prog)
(assq-ref (program-properties proc) 'documentation))
(assq-ref (program-properties prog) 'documentation))

View file

@ -99,6 +99,24 @@ reinstate_vm_cont (struct scm_vm *vp, SCM cont)
memcpy (vp->sp + 1, p->stack_base, p->stack_size * sizeof (SCM));
}
struct vm_unwind_data
{
struct scm_vm *vp;
SCM *sp;
SCM *fp;
SCM this_frame;
};
static void
vm_reset_stack (void *data)
{
struct vm_unwind_data *w = data;
w->vp->sp = w->sp;
w->vp->fp = w->fp;
w->vp->this_frame = w->this_frame;
}
static SCM
vm_cont_mark (SCM obj)
{
@ -182,10 +200,18 @@ vm_heapify_frames_1 (struct scm_vm *vp, SCM *fp, SCM *sp, SCM **destp)
SCM_FRAME_SET_DYNAMIC_LINK (fp, SCM_HEAP_FRAME_POINTER (link));
}
/* Apparently the intention here is to be able to have a frame on the heap,
but data on the stack, so that you can push as much as you want on the
stack; but I think that it's currently causing borkage with nonlocal exits
and the unwind handler, which reinstates the sp and fp, but it's no longer
pointing at a valid stack frame. So disable for now, we'll get back to
this later. */
#if 0
/* Move stack data */
for (; src <= sp; src++, dest++)
*dest = *src;
*destp = dest;
#endif
return frame;
}
@ -519,9 +545,12 @@ SCM_DEFINE (scm_vm_save_stack, "vm-save-stack", 1, 0, 0,
"")
#define FUNC_NAME s_scm_vm_save_stack
{
struct scm_vm *vp;
SCM *dest;
SCM_VALIDATE_VM (1, vm);
SCM_VM_DATA (vm)->last_frame = vm_heapify_frames (vm);
return SCM_VM_DATA (vm)->last_frame;
vp = SCM_VM_DATA (vm);
vp->last_frame = vm_heapify_frames_1 (vp, vp->fp, vp->sp, &dest);
return vp->last_frame;
}
#undef FUNC_NAME

View file

@ -72,6 +72,16 @@ vm_run (SCM vm, SCM program, SCM args)
#if VM_USE_HOOKS
SCM hook_args = SCM_LIST1 (vm);
#endif
struct vm_unwind_data wind_data;
/* dynwind ended in the halt instruction */
scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
wind_data.vp = vp;
wind_data.sp = vp->sp;
wind_data.fp = vp->fp;
wind_data.this_frame = vp->this_frame;
scm_dynwind_unwind_handler (vm_reset_stack, &wind_data, 0);
#ifdef HAVE_LABELS_AS_VALUES
/* Jump table */

View file

@ -112,6 +112,16 @@
#endif
#endif
#ifndef IP_REG
#define IP_REG
#endif
#ifndef SP_REG
#define SP_REG
#endif
#ifndef FP_REG
#define FP_REG
#endif
/*
* Cache/Sync

View file

@ -169,6 +169,7 @@ VM_DEFINE_FUNCTION (set_cdr, "set-cdr!", 2)
ARGS2 (x, y); \
if (SCM_I_INUMP (x) && SCM_I_INUMP (y)) \
RETURN (SCM_BOOL (SCM_I_INUM (x) crel SCM_I_INUM (y))); \
SYNC_REGISTER (); \
RETURN (srel (x, y)); \
}

View file

@ -60,6 +60,7 @@ VM_DEFINE_INSTRUCTION (halt, "halt", 0, 0, 0)
POP (ret);
FREE_FRAME ();
SYNC_ALL ();
scm_dynwind_end ();
return ret;
}