mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
Fix setjmp/longjmp-related crashes on Windows
* libguile/Makefile.am: add new header file setjump-win.h * libguile/continuations.h, libguile/dynstack.c, libguile/dynstack.h, libguile/intrinsics.h, libguile/vm.h: supply custom `setjmp` macro on Windows Mingw implements `setjmp (env)` as a macro that expands to _setjmp (env, faddr) where `faddr` is set to the current frame address. This address is then stored as first element in the jump buffer `env`. When `longjmp` is called, it tries to unwind the stack up to the saved address by calling `RtlUnwindEx` from MSVCRT, which will fail, if the stack frames are interwoven with JIT-generated code, that violate the Windows x64 calling conventions. Thus implement the macro ourselves as _setjmp (env, NULL) which will toggle a code path in `longjmp` that does no unwinding. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
c0bfa3219c
commit
08e26836f1
7 changed files with 40 additions and 0 deletions
|
@ -678,6 +678,7 @@ modinclude_HEADERS = \
|
|||
rw.h \
|
||||
scmsigs.h \
|
||||
script.h \
|
||||
setjump-win.h \
|
||||
simpos.h \
|
||||
smob.h \
|
||||
snarf.h \
|
||||
|
|
|
@ -22,7 +22,11 @@
|
|||
|
||||
|
||||
|
||||
#ifndef _WIN64
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
#include "libguile/setjump-win.h"
|
||||
#endif
|
||||
|
||||
#include "libguile/programs.h"
|
||||
#include "libguile/throw.h"
|
||||
|
|
|
@ -25,7 +25,12 @@
|
|||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _WIN64
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
#include "setjump-win.h"
|
||||
#endif
|
||||
|
||||
#include "control.h"
|
||||
#include "eval.h"
|
||||
|
|
|
@ -22,7 +22,12 @@
|
|||
|
||||
|
||||
|
||||
#ifndef _WIN64
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
#include "libguile/setjump-win.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "libguile/scm.h"
|
||||
|
|
|
@ -24,7 +24,11 @@
|
|||
#error intrinsics.h is private and uninstalled
|
||||
#endif
|
||||
|
||||
#ifndef _WIN64
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
#include "libguile/setjump-win.h"
|
||||
#endif
|
||||
|
||||
#include <libguile/scm.h>
|
||||
|
||||
|
|
17
libguile/setjump-win.h
Normal file
17
libguile/setjump-win.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef _SCM_SETJUMP_WIN_H_
|
||||
#define _SCM_SETJUMP_WIN_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
/* On Windows, `setjmp` expands to _setjmp, which takes a second
|
||||
parameter that is set to the current frame address by default.
|
||||
The address is then stored as first element in the jump buffer.
|
||||
When `longjmp` is called, it tries to unwind the stack up
|
||||
to the saved address, which will fail, if the stack frames are
|
||||
interwoven with JIT-generated code.
|
||||
Set the second parameter to NULL to prevent unwinding. */
|
||||
#undef setjmp
|
||||
#define setjmp(env) _setjmp(env, NULL)
|
||||
|
||||
#endif /* _SCM_SETJUMP_WIN_H_ */
|
||||
|
|
@ -20,7 +20,11 @@
|
|||
#ifndef _SCM_VM_H_
|
||||
#define _SCM_VM_H_
|
||||
|
||||
#ifndef _WIN64
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
#include "libguile/setjump-win.h"
|
||||
#endif
|
||||
|
||||
#include <libguile/gc.h>
|
||||
#include <libguile/programs.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue