[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] branch main updated: Fix setjmp/longjmp-related crashes
From: |
Ludovic Courtès |
Subject: |
[Guile-commits] branch main updated: Fix setjmp/longjmp-related crashes on Windows |
Date: |
Sun, 20 Oct 2024 07:05:33 -0400 |
This is an automated email from the git hooks/post-receive script.
civodul pushed a commit to branch main
in repository guile.
The following commit(s) were added to refs/heads/main by this push:
new 08e26836f Fix setjmp/longjmp-related crashes on Windows
08e26836f is described below
commit 08e26836f1116fba4ef1b674f2f9b37e0e4ebb03
Author: Michael Käppler <xmichael-k@web.de>
AuthorDate: Sat Sep 7 22:52:22 2024 +0200
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>
---
libguile/Makefile.am | 1 +
libguile/continuations.h | 4 ++++
libguile/dynstack.c | 5 +++++
libguile/dynstack.h | 5 +++++
libguile/intrinsics.h | 4 ++++
libguile/setjump-win.h | 17 +++++++++++++++++
libguile/vm.h | 4 ++++
7 files changed, 40 insertions(+)
diff --git a/libguile/Makefile.am b/libguile/Makefile.am
index 59fb5f5fc..5f279a257 100644
--- a/libguile/Makefile.am
+++ b/libguile/Makefile.am
@@ -678,6 +678,7 @@ modinclude_HEADERS = \
rw.h \
scmsigs.h \
script.h \
+ setjump-win.h \
simpos.h \
smob.h \
snarf.h \
diff --git a/libguile/continuations.h b/libguile/continuations.h
index d83bed9b7..ac636512e 100644
--- a/libguile/continuations.h
+++ b/libguile/continuations.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"
diff --git a/libguile/dynstack.c b/libguile/dynstack.c
index 2eec7a7eb..e4ed878c2 100644
--- a/libguile/dynstack.c
+++ b/libguile/dynstack.c
@@ -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"
diff --git a/libguile/dynstack.h b/libguile/dynstack.h
index 4c32a0943..6f0775e40 100644
--- a/libguile/dynstack.h
+++ b/libguile/dynstack.h
@@ -22,7 +22,12 @@
+#ifndef _WIN64
#include <setjmp.h>
+#else
+#include "libguile/setjump-win.h"
+#endif
+
#include <signal.h>
#include "libguile/scm.h"
diff --git a/libguile/intrinsics.h b/libguile/intrinsics.h
index d2ffc847e..8a1c7c04e 100644
--- a/libguile/intrinsics.h
+++ b/libguile/intrinsics.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>
diff --git a/libguile/setjump-win.h b/libguile/setjump-win.h
new file mode 100644
index 000000000..bf06e868b
--- /dev/null
+++ b/libguile/setjump-win.h
@@ -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_ */
+
diff --git a/libguile/vm.h b/libguile/vm.h
index 9681188bd..d5b7138d3 100644
--- a/libguile/vm.h
+++ b/libguile/vm.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>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Guile-commits] branch main updated: Fix setjmp/longjmp-related crashes on Windows,
Ludovic Courtès <=