1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-29 19:30:36 +02:00
guile/libguile/setjump-win.h
Michael Käppler 08e26836f1
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>
2024-10-20 12:14:21 +02:00

17 lines
591 B
C

#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_ */