summaryrefslogtreecommitdiff
path: root/mach_dep.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-04-26 10:54:52 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-04-26 10:54:52 +0300
commitb59413253fa0204d6897a05193c58c42ee0c029c (patch)
treee37457266e42ef8ff700171da80885bb33489d83 /mach_dep.c
parentfcdd0bbabdf112e5bcd8882620877f868b9810ee (diff)
downloadbdwgc-b59413253fa0204d6897a05193c58c42ee0c029c.tar.gz
Avoid multiple 'getcontext failed' warnings if getcontext is broken
Issue #133 (bdwgc). * mach_dep.c [!HAVE_PUSH_REGS && UNIX_LIKE && !NO_GETCONTEXT] (GC_with_callee_saves_pushed): Define getcontext_works static variable; do not call getcontext() if getcontext_works < 0; add comment; set getcontext_works to 1 or -1 (depending whether getcontext is working) if getcontext_works is zero. * misc.c [THREADS && UNIX_LIKE && !NO_GETCONTEXT] (callee_saves_pushed_dummy_fn): New static function (empty). * misc.c [THREADS && UNIX_LIKE && !NO_GETCONTEXT] (GC_init): Call GC_with_callee_saves_pushed(callee_saves_pushed_dummy_fn) if GC_dont_gc or GC_dont_precollect (otherwise it is called by GC_gcollect_inner); add comment.
Diffstat (limited to 'mach_dep.c')
-rw-r--r--mach_dep.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/mach_dep.c b/mach_dep.c
index b65e6dbe..95848971 100644
--- a/mach_dep.c
+++ b/mach_dep.c
@@ -237,6 +237,7 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
/* Older versions of Darwin seem to lack getcontext(). */
/* ARM and MIPS Linux often doesn't support a real */
/* getcontext(). */
+ static signed char getcontext_works = 0; /* (-1) - broken, 1 - works */
ucontext_t ctxt;
# ifdef GETCONTEXT_FPU_EXCMASK_BUG
/* Workaround a bug (clearing the FPU exception mask) in */
@@ -255,12 +256,17 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
# endif
# endif
- if (getcontext(&ctxt) < 0) {
- WARN("getcontext failed:"
- " using another register retrieval method...\n", 0);
- /* E.g., to workaround a bug in Docker ubuntu_32bit. */
- } else {
- context = &ctxt;
+ if (getcontext_works >= 0) {
+ if (getcontext(&ctxt) < 0) {
+ WARN("getcontext failed:"
+ " using another register retrieval method...\n", 0);
+ /* getcontext() is broken, do not try again. */
+ /* E.g., to workaround a bug in Docker ubuntu_32bit. */
+ } else {
+ context = &ctxt;
+ }
+ if (EXPECT(0 == getcontext_works, FALSE))
+ getcontext_works = context != NULL 1 : -1;
}
# ifdef GETCONTEXT_FPU_EXCMASK_BUG
# ifdef X86_64