From c65ea594e92ebf6fb30ece92b063501c8abedf72 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 21 Feb 2014 14:42:24 +0100 Subject: [PATCH] Fix segfault in thread_mark * libguile/threads.c (thread_mark): There is a window in which the thread has a handle but doesn't yet have the set of pointerless freelists, so don't unconditionally dereference t->pointerless_freelists. --- libguile/threads.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/libguile/threads.c b/libguile/threads.c index 7902a9a0d..dd04f6ff9 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -100,21 +100,22 @@ thread_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr, but GC doesn't know to trace them (as they are pointerless), so we need to do that here. See the comments at the top of libgc's gc_inline.h. */ - { - size_t n; - for (n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++) - { - void *chain = t->pointerless_freelists[n]; - if (chain) - { - /* The first link is already marked by the freelist vector, - so we just have to mark the tail. */ - while ((chain = *(void **)chain)) - mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr, - mark_stack_limit, NULL); - } - } - } + if (t->pointerless_freelists) + { + size_t n; + for (n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++) + { + void *chain = t->pointerless_freelists[n]; + if (chain) + { + /* The first link is already marked by the freelist vector, + so we just have to mark the tail. */ + while ((chain = *(void **)chain)) + mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr, + mark_stack_limit, NULL); + } + } + } if (t->vp) mark_stack_ptr = scm_i_vm_mark_stack (t->vp, mark_stack_ptr,