guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Throw an exception when mutating read-only data


From: Andy Wingo
Subject: Re: [PATCH] Throw an exception when mutating read-only data
Date: Fri, 14 Apr 2017 11:04:55 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

Hi Pedro,

On Mon 03 Apr 2017 12:49, Pedro Alves <address@hidden> writes:

> AFAICS, guile uses bare setjmp/longjmp for exceptions.
>
> But, one should not use longjmp to jump out of a signal handler, since
> that leaves the signal mask disabled if the system automatically masks
> the signal on handler entry (which is true on e.g., the Linux kernel).
> Instead, sigsetjmp+siglongjmp should be used, in order to restore
> the signal mask.
>
> Since sigsetjmp is heavy weight (it requires a system call to get the current
> mask [1]), I'd recommend instead to use sigsetjmp/siglongjmp around the
> problematic code area, and then call scm_misc_error back in mainline code (as
> opposed to changing SCM_I_SETJMP/SCM_I_LONGJMP and forcing all exception
> handling to use sigsetjmp+siglongjmp).
>
> [1] - See <https://sourceware.org/ml/gdb-patches/2016-04/msg00249.html>
> and the linked URL for a practical difference that made in GDB.

Thanks very much for this information!  I was unaware of how this
worked.  This is the first SIGSEGV handler I have written :)

In Guile the details are similar as in GDB's try/catch, though with some
slight differences.  Currently the usual way Guile does things is to
SCM_I_SETJMP only once before entering the bytecode interpreter.
Establishing a "catch" within Scheme code re-uses that jump buffer.
Currently the "throw" code will unwind the VM state and then do a
SCM_I_LONGJMP back to the jump buffer that corresponds to that catch,
which will re-enter the bytecode interpreter with the new VM state.
Multiple "catch" instantiations can share the same jump buffer.
Probably at some point in the future we optimize things so that if the
"throw" happens from bytecode, within the same VM invocation as the
"catch", that we can avoid the SCM_I_LONGJMP on abort as well.

All of this applies only to Scheme code though.  If you have C code that
throws an error, it will always SCM_I_LONGJMP; and if you call into the
VM from C or establish a "catch" from C, it will SCM_I_SETJMP before
entering the VM.  So in that situation we'd be seeing the performance
impact for signal mask things.

I guess the conclusion here would be that we would need to measure
performance a bit before making a change like this.

Andy



reply via email to

[Prev in Thread] Current Thread [Next in Thread]